/// <summary> /// The add filters to debug if required. /// </summary> /// <param name="context"> /// The context. /// </param> private static void AddFiltersToDebugIfRequired(ITestApiContext context) { if (context.NeedsDebugInformation()) { context.Debug.Filters = context.Filters; } }
/// <summary> /// Builds the resources for. /// </summary> /// <param name="context">Context containing information about the request.</param> /// <returns> /// <see cref="JsonHomeDocument" /> populated according to current user's permissions. /// </returns> public JsonHomeDocument BuildResourcesFor(ITestApiContext context) { var jsonHomeDocument = new JsonHomeDocument(); foreach (var function in Functions) { var functionName = function.Key; var functionValue = function.Value; var webFunction = new WebFunction( functionValue.Href, functionValue.Relation, functionValue.Templated, CreateHints(functionName, "Active", DetermineAvailableVerbs(functionName, context), null), ulong.MaxValue); var listOfHints = (IEnumerable <HttpVerb>)webFunction.Hints.FirstOrDefault(x => x.Key.Contains("allow")).Value; if (webFunction.RequiredPermissions > 0 && listOfHints.Any()) { jsonHomeDocument.AddFunction(functionName, webFunction); } } return(jsonHomeDocument); }
private static IDebugInformation ExcludeDebugInformation(ITestApiContext testApiContext) { if (!testApiContext.NeedsDebugInformation()) { return(null); } if (testApiContext.DebugLevel == DebugLevel.InternalQueryOnly) { return(new DebugInformation { Filters = testApiContext.Debug.Filters }); } if (testApiContext.DebugLevel == DebugLevel.TimingsOnly) { var debug = new DebugInformation(); testApiContext.Debug.Timings.ForEach(debug.AddTimingEvent); return(debug); } return(testApiContext.Debug); }
/// <summary> /// The build. /// </summary> /// <param name="request"> /// The request. /// </param> /// <param name="responseBuilder"> /// The response builder. /// </param> /// <param name="context"> /// The context. /// </param> /// <typeparam name="T"> /// </typeparam> /// <returns> /// The <see cref="HttpResponseMessage"/>. /// </returns> public HttpResponseMessage Build <T>( HttpRequestMessage request, Func <ResponseEnvelope <T> > responseBuilder, ITestApiContext context) { try { var response = responseBuilder.Invoke(); var httpResponse = request.CreateResponse(HttpStatusCode.OK, response); response.Meta.AddMetaDataInformation("elapsedTimeInMS", context.ElapsedTimeInMS); AddETag(httpResponse, (dynamic)response.Payload, response.ApiVersion); return(httpResponse); } catch (ArgumentNullException ex) { return(request.CreateErrorResponse(HttpStatusCode.BadRequest, ex)); } catch (Exception ex) { return(request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex)); } }
private void Add(ITestApiContext context) { Ticket ticket = new Ticket(); ticket.ID = Guid.NewGuid(); ticket.Subject = "my"; ticket.UserID = context.AuthenticatedUser.Id.ToGuid(); _ticketService.AddTicket(ticket); }
public ResponseEnvelope <Guid> HandleDelete(Guid id, ITestApiContext context) { _ticketService.DeleteTicket(id); var recordCounts = CreateRecordCounts(1); var searchResults = new ApiSearchResult <Guid>(recordCounts, id); return(_responseBuilder.CreateResponse(context, searchResults)); }
/// <summary> /// The create details. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="record"> /// The record. /// </param> /// <typeparam name="TIn"> /// </typeparam> /// <typeparam name="TOut"> /// </typeparam> /// <returns> /// The <see cref="TOut"/>. /// </returns> public TOut CreateDetails <TIn, TOut>(ITestApiContext context, ApiResourceEndPoint endPoint, IApiSearchResult <TIn> record) //// This constraint is to ensure the object being created is an IWebLinkable. The reason for the //// generic is to use in _objectFactory.Create where TOut : IWebLinkable { var recordDetail = this._objectFactory.Create <TOut>(record.Results); AppendFunctionsTo(new[] { recordDetail }, endPoint, context); return(recordDetail); }
public ResponseEnvelope <UserWM> HandleCurrentUserGet(ITestApiContext context) { var user = _userService.GetUser(context.AuthenticatedUser.Id.ToGuid()); var usersWM = _objectFactory.Create <UserWM>(user); var recordCounts = CreateRecordCounts(1); var searchResults = new ApiSearchResult <UserWM>(recordCounts, usersWM); var response = _responseBuilder.CreateResponse(context, searchResults); return(response); }
/// <summary> /// Create the response from the request context and the record. /// </summary> /// <param name="context"> /// Context containing information about the request. /// </param> /// <param name="results"> /// The data record for the request. /// </param> /// <typeparam name="T"> /// The type of object that is being returned from the request. /// </typeparam> /// <returns> /// The <see cref="ResponseEnvelope{T}"/> describing the data for the request. /// </returns> public ResponseEnvelope <T> CreateResponse <T>(ITestApiContext context, IApiSearchResult <T> results) { var response = new ResponseEnvelope <T> { Meta = context.MetaData, Payload = results.Results, RecordCount = CreateRecordCounts(results.RecordCounts), Debug = ExcludeDebugInformation(context), Warnings = context.Warnings.IsNullOrEmpty() ? null : context.Warnings, Errors = context.Errors.IsNullOrEmpty() ? null : context.Errors }; return(response); }
/// <summary> /// The create details. /// </summary> /// <param name="context"> /// The context. /// </param> /// <param name="results"> /// The results. /// </param> /// <typeparam name="TIn"> /// </typeparam> /// <typeparam name="TOut"> /// </typeparam> /// <returns> /// A IEnumerable containing all the results translated. /// </returns> public IEnumerable <TOut> CreateDetails <TIn, TOut>( ITestApiContext context, ApiResourceEndPoint endPoint, IApiSearchResult <IEnumerable <TIn> > results) //// This constraint is to ensure the object being created is an IWebLinkable. The reason for the //// generic is to use in _objectFactory.Create where TOut : IWebLinkable { var recordDetails = context.TimeIt("Transform To Response Type", () => results .Results .Select(record => this._objectFactory.Create <TOut>(record))).ToList(); context.TimeIt("Append Functions", () => AppendFunctionsTo(recordDetails, endPoint, context)); return(recordDetails); }
/// <summary> /// The handle get. /// </summary> /// <param name="context"> /// The context. /// </param> /// <returns> /// The <see cref="ResponseEnvelope"/>. /// </returns> public ResponseEnvelope <IEnumerable <UserWM> > HandleGet(ITestApiContext context) { var results = _unitOfWork.GetRepository <UserEntity>().All(); var users = results.Select(userEntity => _objectFactory.Create <User>(userEntity)); var usersWM = users.Select(user => _objectFactory.Create <UserWM>(user)); var recordCounts = CreateRecordCounts(usersWM.Count()); var searchResults = new ApiSearchResult <IEnumerable <UserWM> >(recordCounts, usersWM); var response = _responseBuilder.CreateResponse(context, searchResults); return(response); }
public ResponseEnvelope <TicketWM> HandlePut(Guid id, TicketWM ticketWM, ITestApiContext context) { var ticket = _objectFactory.Create <Ticket>(ticketWM); _ticketService.UpdateTicket(ticket); var updatedTicket = _ticketService.GetTicket(id); var ticketWMUpadted = _objectFactory.Create <TicketWM>(updatedTicket); var recordCounts = CreateRecordCounts(1); var searchResults = new ApiSearchResult <TicketWM>(recordCounts, ticketWMUpadted); return(_responseBuilder.CreateResponse(context, searchResults)); }
private T CreatePathFromOperation <T>(PatchOperation operation, ITestApiContext context) where T : PatchOperationBase { var validationResult = this._pathFromValidationService.Validate(operation); if (validationResult.HasErrors()) { context.AddError(string.Format("{0} The instruction was ignored.", validationResult)); return(null); } if (operation.Value != null) { context.AddWarning(FormatTooMuchInformationWarningMessage(operation, "value")); } return(this.CreateOperation <T>(operation.Path, operation.From)); }
/// <summary> /// The handle get. /// </summary> /// <param name="context"> /// The context. /// </param> /// <returns> /// The <see cref="ResponseEnvelope"/>. /// </returns> public ResponseEnvelope <IEnumerable <TicketWM> > HandleGet(ITestApiContext context) { var results = _ticketService.GetAllTickets(context.AuthenticatedUser.Id.ToGuid()).ToList(); var apiSearchResult = new ApiSearchResult <IEnumerable <Ticket> >(CreateRecordCounts(results.Count()), results); var ticketWMList = _responseBuilder.CreateDetails <Ticket, TicketWM>(context, ApiResourceEndPointForThisHandler, apiSearchResult); // var ticketWMList = results.Select(ticket => _objectFactory.Create<TicketWM>(ticket)); var recordCounts = CreateRecordCounts(ticketWMList.Count()); var searchResults = new ApiSearchResult <IEnumerable <TicketWM> >(recordCounts, ticketWMList); return(_responseBuilder.CreateResponse(context, searchResults)); }
private T CreatePathValueOperation <T>(PatchOperation operation, ITestApiContext context) where T : PatchOperationBase { var validationResult = this._pathValueValidationService.Validate(operation); if (validationResult.HasErrors()) { context.AddError(string.Format("{0} The instruction was ignored.", validationResult)); return(null); } if (!operation.From.IsNullOrEmpty()) { var warning = FormatTooMuchInformationWarningMessage(operation, "from"); context.AddWarning(warning); } return(this.CreateOperation <T>(operation.Path, operation.Value)); }
public ResponseEnvelope <TicketWM> HandlePost(ITestApiContext context, TicketWM ticketWM) { var ticket = _objectFactory.Create <Ticket>(ticketWM); ticket.ID = Guid.NewGuid(); ticket.UserID = context.AuthenticatedUser.Id; _ticketService.AddTicket(ticket); var addedTicket = _ticketService.GetTicket(ticket.ID); var ticketWMAdded = _objectFactory.Create <TicketWM>(ticket); var recordCounts = CreateRecordCounts(1); var searchResults = new ApiSearchResult <TicketWM>(recordCounts, ticketWMAdded); return(_responseBuilder.CreateResponse(context, searchResults)); }
/// <summary> /// The populate meta data. /// </summary> /// <param name="metaData"> /// The meta data. /// </param> /// <param name="context"> /// The context. /// </param> /// <param name="filters"> /// The filters. /// </param> private static void PopulateMetaData(IMetaDataEnvelope metaData, ITestApiContext context, string filters) { metaData.AddMetaDataInformation("count", context.Count); metaData.AddMetaDataInformation("offset", context.Offset); metaData.AddMetaDataInformation("filters", filters); }
/// <summary> /// Apply the changes in <paramref name="operations"/> to <paramref name="entity"/>. /// </summary> /// <param name="entity"> /// The object to apply the operations too. /// </param> /// <param name="operations"> /// A list of operations that was passed in with the PATCH request. /// </param> /// <param name="context"> /// Context containing information about the request. /// </param> public void Patch(object entity, IEnumerable <PatchOperationBase> operations, ITestApiContext context) { foreach (dynamic operation in operations) { ApplyOperation(entity, operation, context); } }
/// <summary> /// The translate. /// </summary> /// <param name="operations"> /// The operations. /// </param> /// <param name="context"> /// Context containing information about the request. /// </param> /// <returns> /// The patch operations in business object form. /// </returns> public IEnumerable <PatchOperationBase> Translate(IEnumerable <PatchOperation> operations, ITestApiContext context) { Ensure.That <PostRequestEntityDetailsNullException>(operations != null); var operationList = new List <PatchOperationBase>(); foreach (var operation in operations) { var operationInstruction = operation.Operation ?? string.Empty; switch (operationInstruction.ToLowerInvariant()) { case "test": var testOperation = this.CreatePathValueOperation <TestPatchOperation>(operation, context); if (testOperation != null) { operationList.Add(testOperation); } break; case "remove": var removeOperation = this.CreatePathOnlyOperation <RemovePatchOperation>(operation, context); if (removeOperation != null) { operationList.Add(removeOperation); } break; case "add": var addOperation = this.CreatePathValueOperation <AddPatchOperation>(operation, context); if (addOperation != null) { operationList.Add(addOperation); } break; case "replace": var replaceOperation = this.CreatePathValueOperation <ReplacePatchOperation>(operation, context); if (replaceOperation != null) { operationList.Add(replaceOperation); } break; case "move": var moveOperation = this.CreatePathFromOperation <MovePatchOperation>(operation, context); if (moveOperation != null) { operationList.Add(moveOperation); } break; case "copy": var copyOperation = this.CreatePathFromOperation <CopyPatchOperation>(operation, context); if (copyOperation != null) { operationList.Add(copyOperation); } break; default: context.AddError(string.Format(@"Invalid PATCH operation '{0}'. The instruction was ignored.", operation.Operation ?? "null")); break; } } return(operationList); }
public ResponseEnvelope <TicketWM> HandlePatch(Guid entityId, IEnumerable <PatchOperationBase> changes, ITestApiContext context) { var ticketEntity = _ticketService.GetTicket(entityId); var ticket = _objectFactory.Create <Ticket>(ticketEntity); var ticketWM = _objectFactory.Create <TicketWM>(ticket); var operationBases = changes as IList <PatchOperationBase> ?? changes.ToList(); //Todo This logic will be changed when rest of PatchOperation will be decided. var replaceOperatonList = operationBases.Where(operation => operation.GetType() == typeof(ReplacePatchOperation)).ToList(); var invalidOperations = replaceOperatonList.Where(x => x.Path.TrimStart('/').Equals("ticketNumber", StringComparison.OrdinalIgnoreCase)); if (invalidOperations.Any()) { context.AddError("Invalid patch request."); throw new BadRequestException(); } _entityPatcher.Patch(ticketWM, replaceOperatonList, context); _ticketService.UpdateTicket(_objectFactory.Create <Ticket>(ticketWM)); var updatedTicket = _ticketService.GetTicket(entityId); var ticketWMUpadted = _objectFactory.Create <TicketWM>(updatedTicket); var recordCounts = CreateRecordCounts(1); var searchResults = new ApiSearchResult <TicketWM>(recordCounts, ticketWMUpadted); return(_responseBuilder.CreateResponse(context, searchResults)); }
private static void ApplyOperation <T>(T entity, CopyPatchOperation operation, ITestApiContext context) { var path = new Queue <string>(operation.Path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)); }
public void AppendLinksTo(IWebLinkable webLinkable, ApiResourceEndPoint endPoint, ITestApiContext context) { var weblinkType = webLinkable.GetType(); if (!_linkCreators.ContainsKey(webLinkable.GetType())) { return; } _linkCreators[weblinkType].AppendFunctionsTo(webLinkable, endPoint, context); }
private static void ApplyOperation <T>(T entity, RemovePatchOperation operation, ITestApiContext context) { var path = new Queue <string>(operation.Path.Split(new[] { "/" }, StringSplitOptions.RemoveEmptyEntries)); UpdateField(entity, path, default(T), context); }
private static void UpdateField(object entity, Queue <string> path, object value, ITestApiContext context) { var entityType = entity.GetType(); var propertyName = path.Dequeue(); var property = entityType.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); if (property == null) { context.AddError( string.Format("Property Name {0} does not exist in {1} Model", propertyName, entityType.Name)); return; } if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(IDictionary <,>)) { var dictionary = GetDictionaryPropertyValue(entity, path, value, property); value = dictionary; } value = GetCollectionPropertyValue(value, property); if (path.Any()) { var propertyValue = property.GetValue(entity); UpdateField(propertyValue, path, value, context); return; } var strongTypedValue = value is IConvertible ? Convert.ChangeType(value, property.PropertyType) : value; property.SetValue(entity, strongTypedValue); }
/// <summary> /// Gets the specified user. /// </summary> /// <param name="TestContext">The request context.</param> /// <returns> /// Fully built <see cref="JsonHomeDocument"/>. /// </returns> public JsonHomeDocument HandleGet(ITestApiContext testApiContext) { return(this._builder.BuildResourcesFor(testApiContext)); }
private void AppendFunctionsTo <T>(IEnumerable <T> webLinkable, ApiResourceEndPoint endPoint, ITestApiContext context) where T : IWebLinkable { webLinkable.ForEach(linkable => this._functionAppender.AppendLinksTo(linkable, endPoint, context)); }
/// <summary> /// Appends the links to. /// </summary> /// <param name="webLinkable">The <see cref="IWebLinkable" /> object.</param> /// <param name="endPoint"></param> /// <param name="context">Context containing information about the request.</param> //public void AppendFunctionsTo(IWebLinkable webLinkable, ApiResourceEndPoint endPoint, ITestApiContext context) //{ // var webLinkableType = webLinkable.GetType(); // if (webLinkableType != CreatesLinksFor) // { // context.AddWarning( // string.Format( // @"Trying to add functions to invalid type {0} in LightboxDetailFunctionAppender. Operation Cancelled", // webLinkableType)); // return; // } // var securableObjectPermission = // context.AuthenticatedUser.Permissions.FirstOrDefault( // p => p.SecurableObjectType.Equals(SecurableObjectType.OrgUnit)); // webLinkable.Links.Self = "lightbox"; // if (securableObjectPermission == null) // { // AddFunctionsToWebLinkable( // f => f.Value.ResourceEndPoints.Contains(endPoint) && f.Value.Permissions == ulong.MaxValue, // webLinkable.Links); // return; // } // AddFunctionsToWebLinkable( // f => f.Value.ResourceEndPoints.Contains(endPoint) && (f.Value.Permissions & securableObjectPermission.Permissions) > 0 || f.Value.Permissions == ulong.MaxValue, // webLinkable.Links); //} public void AppendFunctionsTo(IWebLinkable webLinkable, ApiResourceEndPoint endPoint, ITestApiContext context) { var webLinkableType = webLinkable.GetType(); if (webLinkableType != CreatesLinksFor) { context.AddWarning( string.Format( @"Trying to add functions to invalid type {0} in LightboxDetailFunctionAppender. Operation Cancelled", webLinkableType)); return; } webLinkable.Links.Self = "tickets"; AddFunctionsToWebLinkable( f => f.Value.ResourceEndPoints.Contains(endPoint) && f.Value.Permissions == ulong.MaxValue, webLinkable.Links); }
private static IEnumerable <HttpVerb> DetermineAvailableVerbs(string function, ITestApiContext context) { if (!VerbMapping.ContainsKey(function)) { return(Enumerable.Empty <HttpVerb>()); } var securableObjectPermission = context.AuthenticatedUser.Permissions.FirstOrDefault( p => p.SecurableObjectType.Equals(SecurableObjectType.Organization)); if (securableObjectPermission == null) { return(Enumerable.Empty <HttpVerb>()); } return (VerbMapping[function].Where( mapping => mapping.Value == ulong.MaxValue || ((mapping.Value & securableObjectPermission.Permissions) > 0)) .Select(mapping => mapping.Key)); }