Additional functional tests for ElementalValueProvider

This commit is contained in:
Ajay Bhargav Baaskaran 2015-02-16 17:50:15 -08:00
parent e282d2a861
commit 9f9dcbe6ec
45 changed files with 368 additions and 48 deletions

View File

@ -9,6 +9,7 @@ using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using ModelBindingWebSite;
using ModelBindingWebSite.Controllers;
using ModelBindingWebSite.Models;
using Newtonsoft.Json;
using Xunit;

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using ModelBindingWebSite;
using ModelBindingWebSite.Models;
using Newtonsoft.Json;
using Xunit;
using ModelBindingWebSite.Controllers;
@ -15,7 +16,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
public class ModelBindingFromQueryTest
{
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(ModelBindingWebSite));
private readonly Action<IApplicationBuilder> _app = new ModelBindingWebSite.Startup().Configure;
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
[Fact]
public async Task FromQuery_CustomModelPrefix_ForParameter()

View File

@ -3,15 +3,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using ModelBindingWebSite;
using ModelBindingWebSite.Models;
using Newtonsoft.Json;
using Xunit;
@ -20,7 +17,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
public class ModelBindingFromRouteTest
{
private readonly IServiceProvider _services = TestHelper.CreateServices(nameof(ModelBindingWebSite));
private readonly Action<IApplicationBuilder> _app = new ModelBindingWebSite.Startup().Configure;
private readonly Action<IApplicationBuilder> _app = new Startup().Configure;
[Fact]
public async Task FromRoute_CustomModelPrefix_ForParameter()

View File

@ -2,16 +2,10 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using ModelBindingWebSite;
using ModelBindingWebSite.Models;
using Newtonsoft.Json;
using Xunit;

View File

@ -11,10 +11,8 @@ using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Core.Collections;
using Microsoft.AspNet.TestHost;
using ModelBindingWebSite;
using ModelBindingWebSite.Models;
using ModelBindingWebSite.ViewModels;
using Newtonsoft.Json;
using Xunit;
@ -1821,7 +1819,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
[Theory]
[MemberData(nameof(ModelStateHasErrorsForValueAndReferenceTypesData))]
public async Task ModelState_HasErrors_ForValueAndReferenceTypes(
string input,
string input,
IEnumerable<string> expectedModelStateErrorMessages)
{
// Arrange
@ -1831,7 +1829,7 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
// Act
var response = await client.PostAsync(
"http://localhost/Validation/CreateRectangle",
"http://localhost/Validation/CreateRectangle",
content);
// Assert
@ -1846,5 +1844,233 @@ namespace Microsoft.AspNet.Mvc.FunctionalTests
(actualErrorMessage) => actualErrorMessage.StartsWith(expectedErrorMessage));
}
}
[Fact]
public async Task BindModelAsync_WithCollection()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new Dictionary<string, string>
{
{ "AddressLines[0].Line", "Street Address 0" },
{ "AddressLines[1].Line", "Street Address 1" },
{ "ZipCode", "98052" },
};
var url = "http://localhost/Person_CollectionBinder/CollectionType";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PutAsync(url, formData);
// Assert
var address = await ReadValue<PersonAddress>(response);
Assert.Equal(2, address.AddressLines.Count);
Assert.Equal("Street Address 0", address.AddressLines[0].Line);
Assert.Equal("Street Address 1", address.AddressLines[1].Line);
Assert.Equal("98052", address.ZipCode);
}
[Fact]
public async Task BindModelAsync_WithCollection_SpecifyingIndex()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new[]
{
new KeyValuePair<string, string>("AddressLines.index", "3"),
new KeyValuePair<string, string>("AddressLines.index", "10000"),
new KeyValuePair<string, string>("AddressLines[3].Line", "Street Address 0"),
new KeyValuePair<string, string>("AddressLines[10000].Line", "Street Address 1"),
};
var url = "http://localhost/Person_CollectionBinder/CollectionType";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PutAsync(url, formData);
// Assert
var address = await ReadValue<PersonAddress>(response);
Assert.Equal(2, address.AddressLines.Count);
Assert.Equal("Street Address 0", address.AddressLines[0].Line);
Assert.Equal("Street Address 1", address.AddressLines[1].Line);
}
[Fact]
public async Task BindModelAsync_WithNestedCollection()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new Dictionary<string, string>
{
{ "Addresses[0].AddressLines[0].Line", "Street Address 00" },
{ "Addresses[0].AddressLines[1].Line", "Street Address 01" },
{ "Addresses[0].ZipCode", "98052" },
{ "Addresses[1].AddressLines[0].Line", "Street Address 10" },
{ "Addresses[1].AddressLines[3].Line", "Street Address 13" },
};
var url = "http://localhost/Person_CollectionBinder/NestedCollectionType";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PostAsync(url, formData);
// Assert
var result = await ReadValue<UserWithAddress>(response);
Assert.Equal(2, result.Addresses.Count);
var address = result.Addresses[0];
Assert.Equal(2, address.AddressLines.Count);
Assert.Equal("Street Address 00", address.AddressLines[0].Line);
Assert.Equal("Street Address 01", address.AddressLines[1].Line);
Assert.Equal("98052", address.ZipCode);
address = result.Addresses[1];
Assert.Single(address.AddressLines);
Assert.Equal("Street Address 10", address.AddressLines[0].Line);
Assert.Null(address.ZipCode);
}
[Fact]
public async Task BindModelAsync_WithIncorrectlyFormattedNestedCollectionValue()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new Dictionary<string, string>
{
{ "Addresses", "Street Address 00" },
};
var url = "http://localhost/Person_CollectionBinder/NestedCollectionType";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PostAsync(url, formData);
// Assert
var result = await ReadValue<UserWithAddress>(response);
var address = Assert.Single(result.Addresses);
Assert.Null(address.AddressLines);
Assert.Null(address.ZipCode);
}
[Fact]
public async Task BindModelAsync_WithNestedCollectionContainingRecursiveRelation()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new Dictionary<string, string>
{
{ "People[0].Name", "Person 0" },
{ "People[0].Parent.Name", "Person 0 Parent" },
{ "People[1].Parent.Name", "Person 1 Parent" },
{ "People[2].Parent", "Person 2 Parent" },
{ "People[1000].Name", "Person 1000 Parent" },
};
var url = "http://localhost/Person_CollectionBinder/NestedCollectionOfRecursiveTypes";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PostAsync(url, formData);
// Assert
var result = await ReadValue<PeopleModel>(response);
Assert.Equal(3, result.People.Count);
var person = result.People[0];
Assert.Equal("Person 0", person.Name);
Assert.Equal("Person 0 Parent", person.Parent.Name);
Assert.Null(person.Parent.Parent);
person = result.People[1];
Assert.Equal("Person 1 Parent", person.Parent.Name);
Assert.Null(person.Parent.Parent);
person = result.People[2];
Assert.Null(person.Name);
Assert.Null(person.Parent);
}
[Fact]
public async Task BindModelAsync_WithNestedCollectionContainingRecursiveRelation_WithMalformedValue()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new Dictionary<string, string>
{
{ "People", "Person 0" },
};
var url = "http://localhost/Person_CollectionBinder/NestedCollectionOfRecursiveTypes";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PostAsync(url, formData);
// Assert
var result = await ReadValue<PeopleModel>(response);
var person = Assert.Single(result.People);
Assert.Null(person.Name);
Assert.Null(person.Parent);
}
[Theory]
[InlineData("true", "false", true)]
[InlineData("false", "true", false)]
public async Task BindModelAsync_MultipleCheckBoxesWithSameKey_BindsFirstValue(string firstValue,
string secondValue,
bool expectedResult)
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string,string>("isValid", firstValue),
new KeyValuePair<string,string>("isValid", secondValue),
};
var url = "http://localhost/Person_CollectionBinder/PostCheckBox";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PostAsync(url, formData);
// Assert
var result = await ReadValue<bool>(response);
Assert.Equal(expectedResult, result);
}
[Fact]
public async Task BindModelAsync_CheckBoxesList_BindSuccessful()
{
// Arrange
var server = TestServer.Create(_services, _app);
var client = server.CreateClient();
var content = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string,string>("userPreferences[0].Id", "1"),
new KeyValuePair<string,string>("userPreferences[0].Checked", "true"),
new KeyValuePair<string,string>("userPreferences[1].Id", "2"),
new KeyValuePair<string,string>("userPreferences[1].Checked", "false"),
};
var url = "http://localhost/Person_CollectionBinder/PostCheckBoxList";
var formData = new FormUrlEncodedContent(content);
// Act
var response = await client.PostAsync(url, formData);
// Assert
var result = await ReadValue<List<UserPreference>>(response);
Assert.True(result[0].Checked);
Assert.False(result[1].Checked);
}
private async Task<TVal> ReadValue<TVal>(HttpResponseMessage response)
{
Assert.True(response.IsSuccessStatusCode);
return JsonConvert.DeserializeObject<TVal>(await response.Content.ReadAsStringAsync());
}
}
}

View File

@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using ModelBindingWebSite;
using ModelBindingWebSite.Models;
using Newtonsoft.Json;
using Xunit;

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq.Expressions;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -7,6 +7,7 @@ using System.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Http;
using Microsoft.Net.Http.Headers;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -1,7 +1,6 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -3,6 +3,7 @@
using System.Collections.Generic;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -0,0 +1,37 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{
public class Person_CollectionBinderController : Controller
{
public PersonAddress CollectionType(PersonAddress address)
{
return address;
}
public UserWithAddress NestedCollectionType(UserWithAddress user)
{
return user;
}
public PeopleModel NestedCollectionOfRecursiveTypes(PeopleModel model)
{
return model;
}
public bool PostCheckBox(bool isValid)
{
return isValid;
}
public IEnumerable<UserPreference> PostCheckBoxList(IEnumerable<UserPreference> userPreferences)
{
return userPreferences;
}
}
}

View File

@ -1,8 +1,8 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -6,6 +6,7 @@ using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -8,7 +8,7 @@ using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using System.Collections.Generic;
using Microsoft.AspNet.Http.Core.Collections;
using Microsoft.AspNet.Http;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{
@ -42,8 +42,8 @@ namespace ModelBindingWebSite.Controllers
prefix: string.Empty,
predicate:
(context, modelName) =>
!string.Equals(modelName, nameof(ModelBindingWebSite.User.Id), StringComparison.Ordinal) &&
!string.Equals(modelName, nameof(ModelBindingWebSite.User.Key), StringComparison.Ordinal));
!string.Equals(modelName, nameof(Models.User.Id), StringComparison.Ordinal) &&
!string.Equals(modelName, nameof(Models.User.Key), StringComparison.Ordinal));
return user;
}

View File

@ -1,12 +1,10 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -7,8 +7,8 @@ using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.WebUtilities;
using ModelBindingWebSite.Services;
using ModelBindingWebSite.ViewModels;
using ModelBindingWebSite.Services;
namespace ModelBindingWebSite
{

View File

@ -1,9 +1,8 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -3,6 +3,7 @@
using System;
using Microsoft.AspNet.Mvc;
using ModelBindingWebSite.Models;
namespace ModelBindingWebSite.Controllers
{

View File

@ -1,8 +1,6 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Mvc;
namespace ModelBindingWebSite
{
public class DefaultCalculatorContext : CalculatorContext

View File

@ -3,7 +3,7 @@
using System.ComponentModel.DataAnnotations;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Address
{

View File

@ -3,7 +3,7 @@
using Microsoft.AspNet.Http;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Book
{

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Company
{

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Country
{

View File

@ -3,7 +3,7 @@
using Microsoft.AspNet.Mvc;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Customer : Person
{

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Department
{

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Document
{

View File

@ -5,7 +5,7 @@
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNet.Mvc;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Employee : Person
{

View File

@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class EmployeeWithBinderMetadata : Employee
{

View File

@ -1,7 +1,7 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class FileDetails
{

View File

@ -3,7 +3,7 @@
using Microsoft.AspNet.Mvc;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class User_FromBody
{

View File

@ -3,7 +3,7 @@
using Microsoft.AspNet.Mvc;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class User_FromForm
{

View File

@ -3,7 +3,7 @@
using System.ComponentModel.DataAnnotations;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class ModelWithValidation
{

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace ModelBindingWebSite.Models
{
public class PeopleModel
{
public List<Person> People { get; set; }
}
}

View File

@ -3,7 +3,7 @@
using System.Collections.Generic;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Person
{

View File

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace ModelBindingWebSite.Models
{
public class PersonAddress
{
public List<StreetAddress> AddressLines { get; set; }
public string ZipCode { get; set; }
}
}

View File

@ -4,7 +4,7 @@
using System.Collections.Generic;
using Microsoft.AspNet.Mvc;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class Resident : Person
{

View File

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace ModelBindingWebSite.Models
{
public class StreetAddress
{
public string Line { get; set; }
}
}

View File

@ -3,7 +3,7 @@
using System.ComponentModel.DataAnnotations;
namespace ModelBindingWebSite
namespace ModelBindingWebSite.Models
{
public class User
{

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace ModelBindingWebSite.Models
{
public class UserPreference
{
public int Id { get; set; }
public bool Checked { get; set; }
}
}

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
namespace ModelBindingWebSite.Models
{
public class UserWithAddress
{
public List<PersonAddress> Addresses { get; set; }
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.ModelBinding;
using Microsoft.Framework.DependencyInjection;
using ModelBindingWebSite.Models;
using ModelBindingWebSite.Services;
namespace ModelBindingWebSite