public async Task Can_Get_TodoItem_WithOwner()
        {
            // Arrange
            var person   = new Person();
            var todoItem = _todoItemFaker.Generate();

            todoItem.Owner = person;
            _context.TodoItems.Add(todoItem);
            _context.SaveChanges();

            var httpMethod = new HttpMethod("GET");
            var route      = $"/api/v1/todo-items/{todoItem.Id}?include=owner";

            var description = new RequestProperties("Get TodoItem By Id", new Dictionary <string, string> {
                { "/todo-items/{id}", "TodoItem Id" },
                { "?include={relationship}", "Included Relationship" }
            });

            // Act
            var response = await _fixture.MakeRequest <TodoItem>(description, httpMethod, route);

            var body = await response.Content.ReadAsStringAsync();

            var deserializedBody = (TodoItem)JsonApiDeSerializer.Deserialize(body, _jsonApiContext);

            // Assert
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.Equal(person.Id, deserializedBody.OwnerId);
            Assert.Equal(todoItem.Id, deserializedBody.Id);
            Assert.Equal(todoItem.Description, deserializedBody.Description);
            Assert.Equal(todoItem.Ordinal, deserializedBody.Ordinal);
        }
        public void Can_Deserialize_Object_With_HasManyRelationship()
        {
            // arrange
            var resourceGraphBuilder = new ResourceGraphBuilder();

            resourceGraphBuilder.AddResource <OneToManyIndependent>("independents");
            resourceGraphBuilder.AddResource <OneToManyDependent>("dependents");
            var resourceGraph = resourceGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ResourceGraph).Returns(resourceGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());
            jsonApiContextMock.Setup(m => m.RelationshipsToUpdate).Returns(new Dictionary <RelationshipAttribute, object>());
            jsonApiContextMock.Setup(m => m.HasManyRelationshipPointers).Returns(new HasManyRelationshipPointers());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object);

            var contentString =
                @"{
                ""data"": {
                    ""type"": ""independents"",
                    ""id"": ""1"",
                    ""attributes"": { },
                    ""relationships"": {
                        ""dependents"": {
                            ""data"": [
                                {
                                    ""type"": ""dependents"",
                                    ""id"": ""2""
                                }
                            ]
                        }
                    }
                }
            }";

            // act
            var result = deserializer.Deserialize <OneToManyIndependent>(contentString);

            // assert
            Assert.NotNull(result);
            Assert.Equal(1, result.Id);
            Assert.NotNull(result.Dependents);
            Assert.NotEmpty(result.Dependents);
            Assert.Single(result.Dependents);

            var dependent = result.Dependents[0];

            Assert.Equal(2, dependent.Id);
        }
Beispiel #3
0
        public void Can_Deserialize_Independent_Side_Of_One_To_One_Relationship_With_Relationship_Body()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <Independent>("independents");
            contextGraphBuilder.AddResource <Dependent>("dependents");
            var contextGraph = contextGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());
            jsonApiContextMock.Setup(m => m.HasOneRelationshipPointers).Returns(new HasOneRelationshipPointers());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object);

            var property = Guid.NewGuid().ToString();
            var content  = new Document
            {
                Data = new DocumentData
                {
                    Type       = "independents",
                    Id         = "1",
                    Attributes = new Dictionary <string, object> {
                        { "property", property }
                    },
                    // a common case for this is deserialization in unit tests
                    Relationships = new Dictionary <string, RelationshipData> {
                        {
                            "dependent", new RelationshipData
                            {
                                SingleData = new ResourceIdentifierObject("dependents", "1")
                            }
                        }
                    }
                }
            };

            var contentString = JsonConvert.SerializeObject(content);

            // act
            var result = deserializer.Deserialize <Independent>(contentString);

            // assert
            Assert.NotNull(result);
            Assert.Equal(property, result.Property);
            Assert.NotNull(result.Dependent);
            Assert.Equal(1, result.Dependent.Id);
        }
Beispiel #4
0
        public void Immutable_Attrs_Are_Not_Included_In_AttributesToUpdate()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <TestResource>("test-resource");
            var contextGraph = contextGraphBuilder.Build();

            var attributesToUpdate = new Dictionary <AttrAttribute, object>();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(attributesToUpdate);

            var jsonApiOptions = new JsonApiOptions();

            jsonApiOptions.SerializerSettings.ContractResolver = new DasherizedResolver();
            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object);

            var content = new Document
            {
                Data = new DocumentData
                {
                    Type       = "test-resource",
                    Id         = "1",
                    Attributes = new Dictionary <string, object>
                    {
                        {
                            "complex-member", new Dictionary <string, string> {
                                { "compound-name", "testName" }
                            }
                        },
                        { "immutable", "value" }
                    }
                }
            };

            var contentString = JsonConvert.SerializeObject(content);

            // act
            var result = deserializer.Deserialize <TestResource>(contentString);

            // assert
            Assert.NotNull(result.ComplexMember);
            Assert.Single(attributesToUpdate);

            foreach (var attr in attributesToUpdate)
            {
                Assert.False(attr.Key.IsImmutable);
            }
        }
Beispiel #5
0
        public void Sets_The_DocumentMeta_Property_In_JsonApiContext()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <Independent>("independents");
            contextGraphBuilder.AddResource <Dependent>("dependents");
            var contextGraph = contextGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var genericProcessorFactoryMock = new Mock <IGenericProcessorFactory>();

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object, genericProcessorFactoryMock.Object);

            var property = Guid.NewGuid().ToString();

            var content = new Document
            {
                Meta = new Dictionary <string, object>()
                {
                    { "foo", "bar" }
                },
                Data = new DocumentData
                {
                    Type       = "independents",
                    Id         = "1",
                    Attributes = new Dictionary <string, object> {
                        { "property", property }
                    },
                    // a common case for this is deserialization in unit tests
                    Relationships = new Dictionary <string, RelationshipData> {
                        { "dependent", new RelationshipData {
                          } }
                    }
                }
            };

            var contentString = JsonConvert.SerializeObject(content);

            // act
            var result = deserializer.Deserialize <Independent>(contentString);

            // assert
            jsonApiContextMock.VerifySet(mock => mock.DocumentMeta = content.Meta);
        }
        public async Task Can_Post_TodoItem()
        {
            // Arrange
            var person = new Person();

            _context.People.Add(person);
            _context.SaveChanges();

            var todoItem = _todoItemFaker.Generate();
            var content  = new
            {
                data = new
                {
                    type       = "todo-items",
                    attributes = new
                    {
                        description = todoItem.Description,
                        ordinal     = todoItem.Ordinal
                    },
                    relationships = new
                    {
                        owner = new
                        {
                            data = new
                            {
                                type = "people",
                                id   = person.Id.ToString()
                            }
                        }
                    }
                }
            };

            var httpMethod = new HttpMethod("POST");
            var route      = $"/api/v1/todo-items";

            var request = new HttpRequestMessage(httpMethod, route);

            request.Content = new StringContent(JsonConvert.SerializeObject(content));
            request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");

            var description = new RequestProperties("Post TodoItem");

            // Act
            var response = await _fixture.MakeRequest <TodoItem>(description, request);

            var body = await response.Content.ReadAsStringAsync();

            var deserializedBody = (TodoItem)JsonApiDeSerializer.Deserialize(body, _jsonApiContext);

            // Assert
            Assert.Equal(HttpStatusCode.Created, response.StatusCode);
            Assert.Equal(todoItem.Description, deserializedBody.Description);
        }
        public void Can_Deserialize_Independent_Side_Of_One_To_One_Relationship_With_String_Keys()
        {
            // arrange
            var resourceGraphBuilder = new ResourceGraphBuilder();

            resourceGraphBuilder.AddResource <IndependentWithStringKey, string>("independents");
            resourceGraphBuilder.AddResource <DependentWithStringKey, string>("dependents");
            var resourceGraph = resourceGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ResourceGraph).Returns(resourceGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());
            jsonApiContextMock.Setup(m => m.HasOneRelationshipPointers).Returns(new HasOneRelationshipPointers());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object);

            var property = Guid.NewGuid().ToString();
            var content  = new Document
            {
                Data = new ResourceObject
                {
                    Type       = "independents",
                    Id         = "natural-key",
                    Attributes = new Dictionary <string, object> {
                        { "property", property }
                    },
                    Relationships = new Dictionary <string, RelationshipData>
                    {
                        { "dependent", new RelationshipData {
                          } }
                    }
                }
            };

            var contentString = JsonConvert.SerializeObject(content);

            // act
            var result = deserializer.Deserialize <IndependentWithStringKey>(contentString);

            // assert
            Assert.NotNull(result);
            Assert.Equal(property, result.Property);
        }
Beispiel #8
0
        public void Can_Deserialize_Complex_List_Types()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <TestResourceWithList>("test-resource");
            var contextGraph = contextGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());
            jsonApiContextMock.Setup(m => m.Options).Returns(new JsonApiOptions
            {
                JsonContractResolver = new CamelCasePropertyNamesContractResolver()
            });

            var genericProcessorFactoryMock = new Mock <IGenericProcessorFactory>();

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object, genericProcessorFactoryMock.Object);

            var content = new Document
            {
                Data = new DocumentData
                {
                    Type       = "test-resource",
                    Id         = "1",
                    Attributes = new Dictionary <string, object> {
                        {
                            "complex-members", new [] {
                                new { compoundName = "testName" }
                            }
                        }
                    }
                }
            };

            // act
            var result = deserializer.Deserialize <TestResourceWithList>(JsonConvert.SerializeObject(content));

            // assert
            Assert.NotNull(result.ComplexMembers);
            Assert.NotEmpty(result.ComplexMembers);
            Assert.Equal("testName", result.ComplexMembers[0].CompoundName);
        }
Beispiel #9
0
        public void Can_Deserialize_Complex_Types_With_Dasherized_Attrs()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <TestResource>("test-resource");
            var contextGraph = contextGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiOptions.SerializerSettings.ContractResolver = new DasherizedResolver(); // <--
            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var genericProcessorFactoryMock = new Mock <IGenericProcessorFactory>();

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object, genericProcessorFactoryMock.Object);

            var content = new Document
            {
                Data = new DocumentData
                {
                    Type       = "test-resource",
                    Id         = "1",
                    Attributes = new Dictionary <string, object> {
                        {
                            "complex-member", new Dictionary <string, string> {
                                { "compound-name", "testName" }
                            }
                        }
                    }
                }
            };

            // act
            var result = deserializer.Deserialize <TestResource>(JsonConvert.SerializeObject(content));

            // assert
            Assert.NotNull(result.ComplexMember);
            Assert.Equal("testName", result.ComplexMember.CompoundName);
        }
Beispiel #10
0
        public void Can_Deserialize_Independent_Side_Of_One_To_One_Relationship()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <Independent>("independents");
            contextGraphBuilder.AddResource <Dependent>("dependents");
            var contextGraph = contextGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var genericProcessorFactoryMock = new Mock <IGenericProcessorFactory>();

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object, genericProcessorFactoryMock.Object);

            var property = Guid.NewGuid().ToString();
            var content  = new Document
            {
                Data = new DocumentData
                {
                    Type       = "independents",
                    Id         = "1",
                    Attributes = new Dictionary <string, object> {
                        { "property", property }
                    }
                }
            };

            var contentString = JsonConvert.SerializeObject(content);

            // act
            var result = deserializer.Deserialize <Independent>(contentString);

            // assert
            Assert.NotNull(result);
            Assert.Equal(property, result.Property);
        }
        public void Can_Deserialize_Complex_Types()
        {
            // arrange
            var resourceGraphBuilder = new ResourceGraphBuilder();

            resourceGraphBuilder.AddResource <TestResource>("test-resource");
            var resourceGraph = resourceGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ResourceGraph).Returns(resourceGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiOptions.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object);

            var content = new Document
            {
                Data = new ResourceObject {
                    Type       = "test-resource",
                    Id         = "1",
                    Attributes = new Dictionary <string, object>
                    {
                        { "complex-member", new { compoundName = "testName" } }
                    }
                }
            };

            // act
            var result = deserializer.Deserialize <TestResource>(JsonConvert.SerializeObject(content));

            // assert
            Assert.NotNull(result.ComplexMember);
            Assert.Equal("testName", result.ComplexMember.CompoundName);
        }
Beispiel #12
0
        public Task <InputFormatterResult> ReadAsync(InputFormatterContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var request = context.HttpContext.Request;

            if (request.ContentLength == 0)
            {
                return(InputFormatterResult.SuccessAsync(null));
            }

            var loggerFactory = GetService <ILoggerFactory>(context);
            var logger        = loggerFactory?.CreateLogger <JsonApiInputFormatter>();

            try
            {
                var body           = GetRequestBody(context.HttpContext.Request.Body);
                var jsonApiContext = GetService <IJsonApiContext>(context);
                var model          = jsonApiContext.IsRelationshipPath ?
                                     JsonApiDeSerializer.DeserializeRelationship(body, jsonApiContext) :
                                     JsonApiDeSerializer.Deserialize(body, jsonApiContext);

                if (model == null)
                {
                    logger?.LogError("An error occurred while de-serializing the payload");
                }

                return(InputFormatterResult.SuccessAsync(model));
            }
            catch (JsonSerializationException ex)
            {
                logger?.LogError(new EventId(), ex, "An error occurred while de-serializing the payload");
                context.HttpContext.Response.StatusCode = 422;
                return(InputFormatterResult.FailureAsync());
            }
        }
        public async Task ShouldReceiveLocationHeader_InResponse()
        {
            // arrange
            var builder = new WebHostBuilder()
                          .UseStartup <Startup>();
            var httpMethod = new HttpMethod("POST");
            var route      = "/api/v1/todo-items";
            var server     = new TestServer(builder);
            var client     = server.CreateClient();
            var request    = new HttpRequestMessage(httpMethod, route);
            var todoItem   = _todoItemFaker.Generate();
            var content    = new
            {
                data = new
                {
                    type       = "todo-items",
                    attributes = new
                    {
                        description = todoItem.Description,
                        ordinal     = todoItem.Ordinal
                    }
                }
            };

            request.Content = new StringContent(JsonConvert.SerializeObject(content));
            request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.api+json");

            // act
            var response = await client.SendAsync(request);

            var body = await response.Content.ReadAsStringAsync();

            var deserializedBody = (TodoItem)JsonApiDeSerializer.Deserialize(body, _jsonApiContext);

            // assert
            Assert.Equal(HttpStatusCode.Created, response.StatusCode);
            Assert.Equal($"/api/v1/todo-items/{deserializedBody.Id}", response.Headers.Location.ToString());
        }
Beispiel #14
0
        public void Sets_Attribute_Values_On_Included_HasOne_Relationships()
        {
            // arrange
            var contextGraphBuilder = new ContextGraphBuilder();

            contextGraphBuilder.AddResource <OneToManyIndependent>("independents");
            contextGraphBuilder.AddResource <OneToManyDependent>("dependents");
            var contextGraph = contextGraphBuilder.Build();

            var jsonApiContextMock = new Mock <IJsonApiContext>();

            jsonApiContextMock.SetupAllProperties();
            jsonApiContextMock.Setup(m => m.ContextGraph).Returns(contextGraph);
            jsonApiContextMock.Setup(m => m.AttributesToUpdate).Returns(new Dictionary <AttrAttribute, object>());
            jsonApiContextMock.Setup(m => m.RelationshipsToUpdate).Returns(new Dictionary <RelationshipAttribute, object>());
            jsonApiContextMock.Setup(m => m.HasManyRelationshipPointers).Returns(new HasManyRelationshipPointers());
            jsonApiContextMock.Setup(m => m.HasOneRelationshipPointers).Returns(new HasOneRelationshipPointers());

            var jsonApiOptions = new JsonApiOptions();

            jsonApiContextMock.Setup(m => m.Options).Returns(jsonApiOptions);

            var deserializer = new JsonApiDeSerializer(jsonApiContextMock.Object);

            var expectedName  = "John Doe";
            var contentString =
                @"{
                ""data"": {
                    ""type"": ""dependents"",
                    ""id"": ""1"",
                    ""attributes"": { },
                    ""relationships"": {
                        ""independent"": {
                            ""data"": {
                                ""type"": ""independents"",
                                ""id"": ""2""
                            }
                        }
                    }
                },
                ""included"": [
                    {
                        ""type"": ""independents"",
                        ""id"": ""2"",
                        ""attributes"": {
                            ""name"": """ + expectedName + @"""
                        }
                    }
                ]
            }";

            // act
            var result = deserializer.Deserialize <OneToManyDependent>(contentString);

            // assert
            Assert.NotNull(result);
            Assert.Equal(1, result.Id);
            Assert.NotNull(result.Independent);
            Assert.Equal(2, result.Independent.Id);
            Assert.Equal(expectedName, result.Independent.Name);
        }