public void AppendIncludedRepresentationRecursive_RecursesWholeTree()
        {
            // Arrange
            var source = new PostBuilder()
                .WithAuthor(PostBuilder.Asimov)
                .WithComment(1, "Comment One")
                .WithComment(2, "Comment Two")
                .Build();

            var sourceList = new List<object>()
            {
                source
            };

            var config = TestModelConfigurationBuilder.BuilderForEverything.Build();

            var mapping = config.GetMapping(typeof(Post));
            var context = new Context(
                new Uri("http://dummy:4242/posts"),
                new string[] { "authors.comments" });

            var transformationHelper = new TransformationHelper(config, new FakeLinkBuilder());

            // Act
            var result = transformationHelper.CreateIncludedRepresentations(sourceList, mapping, context);

            // Assert
            Assert.NotNull(result.Single(x => x.Id == "1" && x.Type == "comments"));
            Assert.NotNull(result.Single(x => x.Id == "2" && x.Type == "comments"));
            Assert.NotNull(result.Single(x => x.Id == "1" && x.Type == "authors"));
            Assert.False(result.Any(x => x.Type == "posts"));
        }
        public void GIVEN_Exception_WHEN_OnActionExecuted_THEN_ExceptionIsInCompoundDocument()
        {
            // Arrange
            var transformer = new JsonApiTransformer(null, null, null);
            var exceptionFilter = new JsonApiExceptionFilter(transformer);


            var post = new PostBuilder()
                .WithAuthor(PostBuilder.Asimov)
                .Build();

            var context = new FilterContextBuilder()
                .WithException("Test exception message")
                .BuildException();

            // Act
            exceptionFilter.OnException(context);

            // Assert
            var result = (ObjectResult)context.Result;
            var value = (CompoundDocument)result.Value;

            Assert.Equal(1, value.Errors.Count());
            Assert.Equal("Test exception message", value.Errors.First().Detail);
            Assert.Equal(500, value.Errors.First().Status);
        }
        public void GIVEN_PostObject_WHEN_OnActionExecuted_THEN_ResponseValid()
        {
            // Arrange
            var actionFilter = GetActionFilterForTestModel();

            var post = new PostBuilder()
                .WithAuthor(PostBuilder.Asimov)
                .Build();

            var context = new FilterContextBuilder()
                .WithResult(new ObjectResult(post))
                .BuildActionExecuted();

            // Act
            actionFilter.OnActionExecuted(context);

            // Assert
            var result = (ObjectResult)context.Result;
            var value = (CompoundDocument)result.Value;
            var resource = (SingleResource)value.Data;

            Assert.Null(value.Errors);
            Assert.Equal(post.Title, resource.Attributes["title"]);
            Assert.Equal(post.AuthorId, resource.Attributes["authorId"]);
        }
        public void AppendIncludedRepresentationRecursive_RecursesWholeTree_No_Duplicates()
        {
            // Arrange
            var duplicateAuthor = PostBuilder.Asimov;

            var firstSource = new PostBuilder()
                .WithAuthor(duplicateAuthor)
                .Build();

            var secondSource = new PostBuilder()
                .WithAuthor(duplicateAuthor)
                .Build();

            var sourceList = new List<object>()
            {
                firstSource,
                secondSource
            };

            var config = TestModelConfigurationBuilder.BuilderForEverything.Build();

            var mapping = config.GetMapping(typeof(Post));
            var context = new Context(
                new Uri("http://dummy:4242/posts"),
                new string[] { "authors.comments" });

            var transformationHelper = new TransformationHelper(config, new FakeLinkBuilder());

            // Act
            var result = transformationHelper.CreateIncludedRepresentations(sourceList, mapping, context);

            // Assert
            Assert.Equal(1, result.Count(x => 
                x.Type == "authors" && 
                x.Id == PostBuilder.Asimov.Id.ToString()));
        }
        public void GIVEN_NoIncludedItems_WHEN_Get_THEN_IncludedItemsAreNull()
        {
            // Arrange
            var source = new PostBuilder()
                .Build();

            var sourceList = new List<object>()
            {
                source
            };

            var config = TestModelConfigurationBuilder.BuilderForEverything.Build();

            var mapping = config.GetMapping(typeof(Post));
            var context = new Context(new Uri("http://dummy:4242/posts"));

            var transformationHelper = new TransformationHelper(config, new FakeLinkBuilder());

            // Act
            var result = transformationHelper.CreateIncludedRepresentations(sourceList, mapping, context);

            // Assert
            Assert.Null(result);
        }
        public void GIVEN_MultipleInclude_WHEN_ActionExecuted_THEN_AllIncludesPresent()
        {
            // Arrange
            var post = new PostBuilder()
                .WithAuthor(PostBuilder.Asimov)
                .WithComment(1, "First")
                .Build();

            var actionFilter = GetActionFilterForTestModel();
            var context = new FilterContextBuilder()
                .WithResult(new ObjectResult(post))
                .WithQuery("include", "authors,comments")
                .BuildActionExecuted();

            // Act
            actionFilter.OnActionExecuted(context);

            // Assert
            var result = (ObjectResult)context.Result;
            var document = (CompoundDocument)result.Value;
            var includedAttributes = document.Included.SelectMany(x => x.Attributes).ToList();

            Assert.Contains(includedAttributes, x =>
                x.Key == "name" &&
                x.Value.ToString() == PostBuilder.Asimov.Name);

            Assert.Contains(includedAttributes, x =>
                x.Key == "body" &&
                x.Value.ToString() == "First");
        }
        public void GIVEN_SingleInclude_WHEN_ActionExecuted_THEN_RelatedIncludePresent()
        {
            // Arrange
            var post = new PostBuilder()
                .WithAuthor(PostBuilder.Asimov)
                .Build();

            var actionFilter = GetActionFilterForTestModel();
            var context = new FilterContextBuilder()
                .WithResult(new ObjectResult(post))
                .WithQuery("include", "authors")
                .BuildActionExecuted();

            // Act
            actionFilter.OnActionExecuted(context);

            // Assert
            var result = (ObjectResult)context.Result;
            var document = (CompoundDocument)result.Value;

            Assert.Equal(PostBuilder.Asimov.Name, document.Included.Single().Attributes["name"]);
        }
        public void GIVEN_IncludesAreNotApplicable_WHEN_ActionExecuted_THEN_400BadRequest(string includePath)
        {
            // Arrange
            var post = new PostBuilder()
                .WithAuthor(PostBuilder.Asimov)
                .Build();

            var actionFilter = GetActionFilterForTestModel();
            var context = new FilterContextBuilder()
                .WithResult(new ObjectResult(post))
                .WithQuery("include", includePath)
                .BuildActionExecuted();

            // Act
            actionFilter.OnActionExecuted(context);

            // Assert
            var result = (HttpStatusCodeResult)context.Result;
            Assert.Equal(400, result.StatusCode);
        }