public void ReturnTrueAndNoErrorMessages_WhenPropertyNameDoesExistOnEntity() { // Arrange var propertyMappingService = new PropertyMappingService(); List <string> errorMessages = new List <string>(); var validationResult = propertyMappingService.ValidMappingExistsFor <CategoryOfmForGet, Category>("Name", ref errorMessages); var actualErrorMessages = JsonConvert.SerializeObject(errorMessages, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented }); var expectedErrorMessages = JsonConvert.SerializeObject( new List <string>(), new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented }); Assert.AreEqual(expectedErrorMessages, actualErrorMessages); Assert.IsTrue(validationResult); }
public void ReturnTrue_WhenQueriedFieldsAreNullOrWhiteSpace(string fields) { // Arrange var propertyMappingService = new PropertyMappingService(); List <string> errorMessages = new List <string>(); var validationResult = propertyMappingService.ValidMappingExistsFor <CategoryOfmForGet, Category>(null, ref errorMessages); var actualErrorMessages = JsonConvert.SerializeObject(errorMessages, new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented }); var expectedErrorMessages = JsonConvert.SerializeObject( new List <string>(), new JsonSerializerSettings() { ReferenceLoopHandling = ReferenceLoopHandling.Ignore, Formatting = Formatting.Indented }); Assert.AreEqual(expectedErrorMessages, actualErrorMessages); Assert.IsTrue(validationResult); }
public void Given_A_Non_Valid_Mapping_When_ValidMappingExistsFor_Is_Called_Then_Return_False() { // Arrange // Test setup var pmd = new Dictionary <string, PropertyMappingValue> { { "Id", new PropertyMappingValue(new List <string>() { "Id" }) }, { "Name", new PropertyMappingValue(new List <string>() { "FirstName", "LastName" }) } }; var pm = new PropertyMapping <Cat, Dog>(pmd); var pms = new PropertyMappingService(); pms.AddPropertyMapping <Cat, Dog>(pm); // Act // Do the thing you want to test var result = pms.ValidMappingExistsFor <Cat, Dog>("non valid mapping"); // Assert //Did the thing you did actually work Assert.False(result); }
public void GetPropertyMapping_ThreePropertyMappings_Returns3() { var propertyMappingService = new PropertyMappingService(); var organizationPropertyMapping = propertyMappingService.GetPropertyMapping <OrganizationDto, Organization>(); Assert.Equal(3, organizationPropertyMapping.Count); }
public void ThrowPropertyNotFoundException_WhenCachedEntityIsNull() { // Arrange var propertyMappingService = new PropertyMappingService(); // Act and Assert Assert.Throws <PropertyMappingNotFoundException>(() => propertyMappingService.GetPropertyMapping <Category, CategoryOfmForGet>()); // Throws, because order must be switched to <CategoryOfmForGet, Category> }
public void ThrowsExceptionOrderById(PropertyMappingService property) { var parameters = new StudentParameters { OrderBy = "Id", }; var sut = new StudentService(DbContextHelper.SeedRepo(property), new TypeHelperService(), new PropertyMappingService()); Assert.Throws <ArgumentException>(() => sut.GetPagedList(parameters)); }
public void GetPropertyMapping_ThreePropertyMappinga_ReturnsTheExpectedOnes() { var propertyMappingService = new PropertyMappingService(); var organizationPropertyMapping = propertyMappingService.GetPropertyMapping <OrganizationDto, Organization>(); Assert.Contains(organizationPropertyMapping["Id"].DestinationProperties, p => p == "Id"); Assert.Contains(organizationPropertyMapping["Name"].DestinationProperties, p => p == "Name"); Assert.Contains(organizationPropertyMapping["Description"].DestinationProperties, p => p == "Description"); }
public void Given_Invalid_PropertyMapping_When_GetPropertyMapping_Is_Called_Then_Throws_Exception() { var pms = new PropertyMappingService(); var exception = Assert.Throws <System.Exception>((() => pms.GetPropertyMapping <Cat, Cat>())); Assert.Equal("Cannot find exact property mapping instance for " + "Users.API.UnitTests.Models.Cat,Users.API.UnitTests.Models.Cat", exception.Message); }
public void ReturnsChangedPaginationWithSpecifiedPageNumber(PropertyMappingService property) { var parameters = new StudentParameters { PageSize = 2, PageNumber = 2 }; var sut = new StudentService(DbContextHelper.SeedRepo(property), new TypeHelperService(), new PropertyMappingService()); var actual = sut.GetPagedList(parameters); Assert.Equal(2, actual.CurrentPage); }
public void ReturnsCorrectOrderByTitle(PropertyMappingService property) { var parameters = new StudentParameters { OrderBy = "Name", }; var sut = new StudentService(DbContextHelper.SeedRepo(property), new TypeHelperService(), new PropertyMappingService()); var actual = sut.GetPagedList(parameters); Assert.Equal("Dummy", actual?[0]?.Name); }
public FestivalsRepositoryTestBase() { ContextBase = FestivalsDbContextFactory.Create(); PropertyMappingServiceBase = new PropertyMappingService(); MedievalFestivalsRepositoryBase = new FestivalsRepository(ContextBase, PropertyMappingServiceBase); FestivalsResourceParametersBase = new FestivalsResourceParameters(); DateTimeMock = new Mock <IDateTimeService>(); DateTimeMock.Setup(m => m.Now).Returns(DateTime.Now); }
public void Given_NullOrWhiteSpace_Mapping_When_ValidMappingExistsFor_Is_Called_Then_Return_False() { var pmd = new Dictionary <string, PropertyMappingValue> { { "Id", new PropertyMappingValue(new List <string>() { "Id" }) }, { "Name", new PropertyMappingValue(new List <string>() { "FirstName", "LastName" }) } }; var pm = new PropertyMapping <Cat, Dog>(pmd); var pms = new PropertyMappingService(); pms.AddPropertyMapping <Cat, Dog>(pm); var result = pms.ValidMappingExistsFor <Cat, Dog>(""); Assert.True(result); }
public async Task <IActionResult> GetBanknotes(CurrenciesResourceParameters resourceParameters, [FromHeader(Name = "Accept")] string mediaType) { if (!PropertyMappingService.ValidMappingExistsFor <Banknote>(resourceParameters.OrderBy)) { return(BadRequest()); } if (!TypeHelper.TypeHasProperties <BanknoteDto>(resourceParameters.Fields)) { return(BadRequest()); } var retrievedBanknotes = await _banknoteService.FindBanknotes(resourceParameters); var banknotes = _mapper.Map <IEnumerable <BanknoteDto> >(retrievedBanknotes); var shapedBanknotes = banknotes.ShapeData(resourceParameters.Fields); if (mediaType == "application/json+hateoas") { if (!string.IsNullOrEmpty(resourceParameters.Fields) && !resourceParameters.Fields.ToLowerInvariant().Contains("id")) { return(BadRequest("Field parameter 'id' is required")); } var paginationMetadata = new { totalCount = retrievedBanknotes.TotalCount, pageSize = retrievedBanknotes.PageSize, currentPage = retrievedBanknotes.CurrentPage, totalPages = retrievedBanknotes.TotalPages }; Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(paginationMetadata)); var links = CreateBanknotesLinks(resourceParameters, retrievedBanknotes.HasNext, retrievedBanknotes.HasPrevious); var linkedBanknotes = shapedBanknotes.Select(banknote => { var banknoteAsDictionary = banknote as IDictionary <string, object>; var banknoteLinks = CreateBanknoteLinks((Guid)banknoteAsDictionary["Id"], resourceParameters.Fields); banknoteAsDictionary.Add("links", banknoteLinks); return(banknoteAsDictionary); }); var linkedCollectionResource = new LinkedCollectionResource { Value = linkedBanknotes, Links = links }; return(Ok(linkedCollectionResource)); } else { var previousPageLink = retrievedBanknotes.HasPrevious ? CreateBanknotesResourceUri(resourceParameters, ResourceUriType.PreviousPage) : null; var nextPageLink = retrievedBanknotes.HasNext ? CreateBanknotesResourceUri(resourceParameters, ResourceUriType.NextPage) : null; var paginationMetadata = new { totalCount = retrievedBanknotes.TotalCount, pageSize = retrievedBanknotes.PageSize, currentPage = retrievedBanknotes.CurrentPage, totalPages = retrievedBanknotes.TotalPages, previousPageLink, nextPageLink, }; Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(paginationMetadata)); return(Ok(shapedBanknotes)); } }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(setupAction => { setupAction.ReturnHttpNotAcceptable = true; var jsonOutputFormatter = setupAction.OutputFormatters.OfType <JsonOutputFormatter>().FirstOrDefault(); if (jsonOutputFormatter != null) { jsonOutputFormatter.SupportedMediaTypes.Add("application/vnd.AO.json+hateoas"); } }) .AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var connectionString = Configuration["ConnectionStrings:AoDB"]; services.AddDbContext <AOContext>(x => x.UseSqlServer(connectionString, y => y.MigrationsAssembly("AoApi.Data"))); services.AddScoped <IEmployeeRepository, EmployeeRepository>(); services.AddScoped <IJobRepository, JobRepository>(); services.AddScoped <IRoleRepository, RoleRepository>(); services.AddScoped <IScheduleRepository, ScheduleRepository>(); services.AddScoped <IUserRepository, UserRepository>(); services.AddScoped <IWorkhoursRepository, WorkhoursRepository>(); services.AddSingleton <IActionContextAccessor, ActionContextAccessor>(); services.AddScoped <IUrlHelper, UrlHelper>(implementationFactory => { var actionContext = implementationFactory.GetService <IActionContextAccessor>().ActionContext; return(new UrlHelper(actionContext)); }); services.AddSingleton <IPropertyMappingService, PropertyMappingService>(implementationFactory => { var pms = new PropertyMappingService(); pms.AddPropertyMapping <EmployeeDtoForMultiple, Employee>(new Dictionary <string, IEnumerable <string> >(StringComparer.OrdinalIgnoreCase) { { "Id", new List <string>() { "Id" } }, { "Name", new List <string>() { "FirstName", "LastName" } }, { "Address", new List <string>() { "City", "Country", "Street" } } }); return(pms); }); services.AddScoped <IPaginationUrlHelper, PaginationUrlHelper>(); services.AddScoped <IHateoasHelper, HateoasHelper>(); services.AddTransient <ITypeHelperService, TypeHelperService>(); services.AddScoped <IControllerHelper, ControllerHelper>(); services.AddSwaggerGen(setupAction => { setupAction.EnableAnnotations(); setupAction.SwaggerDoc("v1", new Info { Title = "Administrative Organizer Api", Version = "v1" }); }); }
private IQueryable <Book> OrderBy(string orderBy) { var propertyMappingService = new PropertyMappingService(); return(_books.AsQueryable().ApplySort(orderBy, propertyMappingService.GetPropertyMapping <BookDto, Book>())); }
public void ConfigureServices(IServiceCollection services) { services.AddMvc(setupAction => { setupAction.ReturnHttpNotAcceptable = true; setupAction.OutputFormatters.Add(new XmlDataContractSerializerOutputFormatter()); //setupAction.InputFormatters.Add(new XmlDataContractSerializerInputFormatter()); var xmlDataContractSerializerInputFormatter = new XmlDataContractSerializerInputFormatter(); xmlDataContractSerializerInputFormatter.SupportedMediaTypes .Add("application/jmd.jasonmorsleydev.user.full+xml"); setupAction.InputFormatters.Add(xmlDataContractSerializerInputFormatter); var jsonInputFormatter = setupAction.InputFormatters.OfType <JsonInputFormatter>().FirstOrDefault(); if (jsonInputFormatter != null) { jsonInputFormatter.SupportedMediaTypes.Add("application/jmd.jasonmorsleydev.user.full+json"); } var jsonOutputFormatter = setupAction.OutputFormatters.OfType <JsonOutputFormatter>().FirstOrDefault(); if (jsonOutputFormatter != null) { jsonOutputFormatter.SupportedMediaTypes.Add("application/jmd.jasonmorsleydev.hateoas+json"); } if (jsonOutputFormatter != null) { // remove text/json as it isn't the approved media type // for working with JSON at API level if (jsonOutputFormatter.SupportedMediaTypes.Contains("text/json")) { jsonOutputFormatter.SupportedMediaTypes.Remove("text/json"); } } }) .AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }); //Here we register the DBContext, and get a connection string from app settings. //It is only to be used during development as in production we will store it in the environment variable var connectionString = Configuration["connectionStrings:userDBConnectionString"]; services.AddDbContext <UserContext>(opt => opt.UseSqlServer(connectionString)); //Registering the repo services.AddScoped <IUsersRepository, UsersRepository>(); services.AddSingleton <IActionContextAccessor, ActionContextAccessor>(); services.AddScoped <IUrlHelper>(implementationFactory => { var actionContext = implementationFactory.GetService <IActionContextAccessor>().ActionContext; return(new UrlHelper(actionContext)); }); services.AddTransient <IPropertyMappingService>(propertyMappingService => { var pms = new PropertyMappingService(); var dictionary = new Dictionary <string, PropertyMappingValue>(); dictionary.Add("Id", new PropertyMappingValue(new List <string>() { "Id" })); dictionary.Add("Name", new PropertyMappingValue(new List <string>() { "FirstName", "LastName" })); var propertyMapping = new PropertyMapping <UserDto, User>(dictionary); pms.AddPropertyMapping <UserDto, User>(propertyMapping); return(pms); }); services.AddTransient <ITypeHelperService, TypeHelperService>(); services.AddHttpCacheHeaders((expirationModelOptions) => { expirationModelOptions.MaxAge = 600; }, (validationModelOptions) => { validationModelOptions.MustRevalidate = true; }); services.AddResponseCaching(); services.AddMemoryCache(); services.Configure <IpRateLimitOptions>((options) => { options.GeneralRules = new List <RateLimitRule>() { new RateLimitRule() { Endpoint = "*", Limit = 1000, Period = "5m" }, new RateLimitRule() { Endpoint = "*", Limit = 200, Period = "10s" } }; }); services.AddSingleton <IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>(); services.AddSingleton <IIpPolicyStore, MemoryCacheIpPolicyStore>(); //services.AddSingleton<IUsersRepository, UsersRepository>(); services.AddAutoMapper(typeof(Startup)); services.AddSwaggerGen(setupAction => { setupAction.SwaggerDoc("UserOpenAPISpecification", new OpenApiInfo() { Title = "User API", Version = "1", Description = "Through this API you can access users.", Contact = new OpenApiContact() { Email = "*****@*****.**", Name = "Jason Morsley", //Url = new Uri("https://www.jasonmorsley.dev") }, //License = new OpenApiLicense() //{ // Name = "MIT License", // Url = new Uri("https://opensource.org/licenses/MIT") //} }); var xmlCommentsFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentsFile); setupAction.IncludeXmlComments(xmlCommentsFullPath); }); }
internal string OrderByLinq <TModel, TEntity>() { return(PropertyMappingService.DynamicSort <TModel, TEntity>(this.OrderBy)); }
public void OrderByNullSourceShouldThrowArugmentNullException() { var propertyMappingService = new PropertyMappingService(); }
public void ReturnsTrueValidFields(string field, PropertyMappingService property) => Assert.True(property.ValidMappingExistsFor <DummyEntityDto, DummyEntity>(field));
public void ReturnsCorrectTotalPages(int pageSize, int pageNumber, int totalPages, PropertyMappingService property) { var parameters = new StudentParameters { PageSize = pageSize, PageNumber = pageNumber, }; var sut = new StudentService(DbContextHelper.SeedRepo(property), new TypeHelperService(), new PropertyMappingService()); var actual = sut.GetPagedList(parameters); Assert.Equal(totalPages, actual.TotalPages); }
public IActionResult GetAuthors(AuthorsResourceParameters authorsResourceParameters, [FromHeader(Name = "Accept")] string mediaType) { if (!PropertyMappingService.ValidMappingExistsFor <AuthorDto, Author>(authorsResourceParameters.OrderBy)) { return(BadRequest()); } if (!TypeHelperService.TypeHasProperties <AuthorDto>(authorsResourceParameters.Fields)) { return(BadRequest()); } var authorsFromRepo = LibraryRepository.GetAuthors(authorsResourceParameters); if (authorsFromRepo == null) { return(NotFound()); } var authorsModel = Mapper.Map <IEnumerable <AuthorDto> >(authorsFromRepo); if (mediaType == "application/vnd.marvin.hateoas+json") { var paginationMetadata = new { totalCount = authorsFromRepo.TotalCount, pageSize = authorsFromRepo.PageSize, currentPage = authorsFromRepo.CurrentPage, totalPages = authorsFromRepo.TotalPages, }; Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(paginationMetadata)); var links = CreateLinksForAuthors(authorsResourceParameters, authorsFromRepo.HasNext, authorsFromRepo.HasPrevious); var shapedAuthors = authorsModel.ShapeData(authorsResourceParameters.Fields); var shapedAuthorsWithLinks = shapedAuthors.Select(author => { var authorAsDictionary = author as IDictionary <string, object>; var authorLinks = CreateLinksForAuthor((Guid)authorAsDictionary["Id"], authorsResourceParameters.Fields); authorAsDictionary.Add("links", authorLinks); return(authorAsDictionary); }); var linkedCollectionResource = new { values = shapedAuthorsWithLinks, links = links }; return(Ok(linkedCollectionResource)); } else { var previousPageLink = authorsFromRepo.HasPrevious ? CreateAuthorsResourceUri(authorsResourceParameters, ResourceUriType.PreviousPage) : null; var nextPageLink = authorsFromRepo.HasNext ? CreateAuthorsResourceUri(authorsResourceParameters, ResourceUriType.NextPage) : null; var paginationMetadata = new { totalCount = authorsFromRepo.TotalCount, pageSize = authorsFromRepo.PageSize, currentPage = authorsFromRepo.CurrentPage, totalPages = authorsFromRepo.TotalPages, previousPageLink = previousPageLink, nextPageLink = nextPageLink }; Response.Headers.Add("X-Pagination", JsonConvert.SerializeObject(paginationMetadata)); return(Ok(authorsModel.ShapeData(authorsResourceParameters.Fields))); } }
public AuthorsController(ILibraryRepository libraryRepository, IUrlHelper urlHelper, PropertyMappingService propertyMappingService) { _libraryRepository = libraryRepository; _urlHelper = urlHelper; _propertyMappingService = propertyMappingService; }
public CategoriesApiController() { repo = new CategoriesRepository(); mappingService = new PropertyMappingService(); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(setupAction => { setupAction.ReturnHttpNotAcceptable = true; var jsonOutputFormatter = setupAction.OutputFormatters.OfType <JsonOutputFormatter>().FirstOrDefault(); if (jsonOutputFormatter != null) { jsonOutputFormatter.SupportedMediaTypes.Add("application/vnd.BD.json+hateoas"); } }) .AddJsonOptions(options => { options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); }) .SetCompatibilityVersion(CompatibilityVersion.Version_2_1); var connectionString = Configuration["ConnectionStrings:AlbumsDB"]; services.AddDbContext <AlbumReviewContext>(x => x.UseSqlServer(connectionString, y => y.MigrationsAssembly("AlbumReview.Data"))); services.AddScoped <IPaginationUrlHelper, PaginationUrlHelper>(); services.AddScoped <IControllerHelper, ControllerHelper>(); services.AddScoped <IHateoasHelper, HateoasHelper>(); services.AddScoped <IArtistRepository, ArtistRepository>(); services.AddScoped <IAlbumRepository, AlbumRepository>(); services.AddScoped <IReviewRepository, ReviewRepository>(); services.AddSingleton <IActionContextAccessor, ActionContextAccessor>(); services.AddScoped <IUrlHelper, UrlHelper>(implementationFactory => { var actionContext = implementationFactory.GetService <IActionContextAccessor>().ActionContext; return(new UrlHelper(actionContext)); }); services.AddSingleton <IPropertyMappingService, PropertyMappingService>(implementationFactory => { var pms = new PropertyMappingService(); pms.AddPropertyMapping <ArtistDto, Artist>(new Dictionary <string, IEnumerable <string> >(StringComparer.OrdinalIgnoreCase) { { "Id", new List <string>() { "Id" } }, { "StageName", new List <string>() { "StageName" } }, { "Age", new List <string>() { "DateOfBirth" } }, { "Name", new List <string>() { "FirstName", "LastName" } } }); pms.AddPropertyMapping <ReviewDto, Review>(new Dictionary <string, IEnumerable <string> >(StringComparer.OrdinalIgnoreCase) { { "Id", new List <string>() { "Id" } }, { "SubmittedReview", new List <string>() { "SubmittedReview" } }, { "Rating", new List <string>() { "Rating" } }, { "Submitted", new List <string>() { "Submitted" } } }); return(pms); }); services.AddTransient <ITypeHelperService, TypeHelperService>(); }
public ProductsApiController() { productsRepo = new ProductsRepository(); mappingService = new PropertyMappingService(); }