public void DerivedNavPropertyModelValidation() { var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { "/$metadata" }, XPaths = new string[] { "//edmx:DataServices" }, } }; SendRequestAndVerifyXPaths(testCases, formats: new string[] { UnitTestsUtil.MimeApplicationXml }); }
public void FilterEntitySetWithTypeIdentifier() { var testVersion = new ServiceVersions(); string xPath = "/atom:entry[atom:category/@term='#" + ManagerTypeName + "' and atom:id='http://host/People(2)' and atom:content/adsm:properties/ads:ID='2']"; DerivedPropertyTestCase[] testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}", PeopleTypeName) }, XPaths = GetLinks( GetLinksForPeopleEntity("2", ManagerTypeName), "count(/atom:feed/atom:entry)=7", "/atom:feed" + xPath), Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}", ManagerTypeName)}, XPaths = new string[] { "count(/atom:feed/atom:entry)=2", "/atom:feed" + xPath }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}", EmployeeTypeName)}, XPaths = new string[] { "count(/atom:feed/atom:entry)=5", "/atom:feed" + xPath }, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedPropertyUpdateTests() { #region Update Requests to Top Level Entity (With Type Identifier and most derived type) - specifying the type name is optional { var payloadGenerators = new PayloadBuilder[] { new PayloadBuilder() .AddProperty("Name", "Anthony") .AddProperty("Manager", new PayloadBuilder() { Uri = "/People(5)" }), new PayloadBuilder() { TypeName = ManagerTypeName } .AddProperty("Name", "Anthony") .AddProperty("Manager", new PayloadBuilder() { Uri = "/People(5)" }), }; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}", ManagerTypeName) }, HttpMethods = new string[] { "PATCH" }, StatusCode = 204, MinProtocolVersion = ODataProtocolVersion.V4, VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { String.Format("/People(2)/{0}", ManagerTypeName) }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + ManagerTypeName + "' and contains(atom:id, 'People(2)') and atom:content/adsm:properties[ads:ID='2' and ads:Name='Anthony']]" } } } }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}", ManagerTypeName) }, HttpMethods = new string[] { "PATCH" }, StatusCode = 204, Version = new ServiceVersions(), VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { String.Format("/People(2)/{0}", ManagerTypeName) }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + ManagerTypeName + "' and contains(atom:id, 'People(2)') and atom:content/adsm:properties[ads:ID='2' and ads:Name='Anthony']]" } } } } }; SendRequestAndVerifyXPaths(testCases, payloads: payloadGenerators); } #endregion Update Requests to Top Level Entity (With Type Identifier and most derived type) #region Update Requests to Top Level Entity (With Type Identifier and not most derived type) - must specify the type name { var payloadGenerators = new PayloadBuilder[] { new PayloadBuilder() { TypeName = EmployeeTypeName } .AddProperty("Name", "Sarah") .AddProperty("Manager", new PayloadBuilder() { Uri = "/People(2)" }) }; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(3)/{0}", EmployeeTypeName) }, HttpMethods = new string[] { "PATCH"}, StatusCode = 204, MinProtocolVersion = ODataProtocolVersion.V4, VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { String.Format("/People(3)/{0}", EmployeeTypeName) }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and contains(atom:id, 'People(3)') and atom:content/adsm:properties[ads:ID='3' and ads:Name='Sarah']]" } } } }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(3)/{0}", EmployeeTypeName) }, HttpMethods = new string[] { "PATCH" }, StatusCode = 204, Version = new ServiceVersions(), VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { String.Format("/People(3)/{0}", EmployeeTypeName) }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and contains(atom:id, 'People(3)') and atom:content/adsm:properties[ads:ID='3' and ads:Name='Sarah']]" } } } } }; SendRequestAndVerifyXPaths(testCases, payloads: payloadGenerators); } #endregion Update Requests to Top Level Entity (With Type Identifier and not most derived type) #region Update Requests to Navigation Collection Property { var payloadGenerators = new PayloadBuilder[] { new PayloadBuilder() { TypeName = EmployeeTypeName } .AddProperty("Name", "Sarah") .AddProperty("Manager", new PayloadBuilder() { Uri = "/People(2)" }), }; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}/DirectReports(3)", ManagerTypeName), String.Format("/People(2)/{0}/DirectReports(3)/{1}", ManagerTypeName, EmployeeTypeName) }, HttpMethods = new string[] { "PATCH" }, StatusCode = 204, MinProtocolVersion = ODataProtocolVersion.V4, VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { "/People(3)" }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and contains(atom:id, 'People(3)') and atom:content/adsm:properties[ads:ID='3' and ads:Name='Sarah']]" } } } }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}/DirectReports(3)", ManagerTypeName), String.Format("/People(2)/{0}/DirectReports(3)/{1}", ManagerTypeName, EmployeeTypeName) }, HttpMethods = new string[] { "PATCH" }, StatusCode = 204, Version = new ServiceVersions(), VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { "/People(3)" }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and contains(atom:id, 'People(3)') and atom:content/adsm:properties[ads:ID='3' and ads:Name='Sarah']]" } } } } }; SendRequestAndVerifyXPaths(testCases, payloads: payloadGenerators); } #endregion Update Requests to Top Level Entity (With Type Identifier and not most derived type) }
public void DerivedPropertyInsertTests() { var testVersion = new ServiceVersions(); #region POST to Top Level Entity Set (With Type Identifier and most derived type) - type name is optional { var payloadGenerators = new PayloadBuilder[] { new PayloadBuilder() .AddProperty("ID", 10) .AddProperty("Name", "Anthony") .AddNavigationReferenceProperty("Manager", new PayloadBuilder() { Uri = "/People(5)" }), new PayloadBuilder() { TypeName = ManagerTypeName } .AddProperty("ID", 10) .AddProperty("Name", "Anthony") .AddNavigationReferenceProperty("Manager", new PayloadBuilder() { Uri = "/People(5)" }) }; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}", ManagerTypeName), }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + ManagerTypeName + "' and contains(atom:id, 'People(10)') and atom:content/adsm:properties[ads:ID='10' and ads:Name='Anthony']]" }, HttpMethods = new string[] { "POST" }, StatusCode = 201, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases, payloads: payloadGenerators); } #endregion POST to Top Level Entity Set (With Type Identifier and most derived type) #region POST to Top Level Entity Set (With Type Identifier and not most derived type) - type name is required { var payloadGenerators = new PayloadBuilder[] { new PayloadBuilder() { TypeName = EmployeeTypeName } .AddProperty("ID", 10) .AddProperty("Name", "Sarah") .AddNavigationReferenceProperty("Manager", new PayloadBuilder() { Uri = "/People(2)" }) }; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}", EmployeeTypeName), }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and contains(atom:id, 'People(10)') and atom:content/adsm:properties[ads:ID='10' and ads:Name='Sarah']]" }, HttpMethods = new string[] { "POST" }, StatusCode = 201, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases, payloads: payloadGenerators); } #endregion POST to Top Level Entity Set (With Type Identifier and not most derived type) #region POST to Navigation Collection Property { var payloadGenerators = new PayloadBuilder[] { new PayloadBuilder() { TypeName = EmployeeTypeName } .AddProperty("ID", 10) .AddProperty("Name", "Sarah") .AddNavigationReferenceProperty("Manager", new PayloadBuilder() { Uri = "/People(2)" }), new PayloadBuilder() { TypeName = EmployeeTypeName } .AddProperty("ID", 10) .AddProperty("Name", "Sarah") .AddNavigationReferenceProperty("Manager", new PayloadBuilder() { Uri = "/People(2)" }) }; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}/DirectReports", ManagerTypeName), String.Format("/People(2)/{0}/DirectReports/{1}", ManagerTypeName, EmployeeTypeName) }, XPaths = new string[] { "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and contains(atom:id, 'People(10)') and atom:content/adsm:properties[ads:ID='10' and ads:Name='Sarah']]" }, HttpMethods = new string[] { "POST" }, StatusCode = 201, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases, payloads: payloadGenerators); } #endregion POST to Navigation Collection Property }
public void ExpandWithSDP() { foreach (var service in services) { service.PageSizeCustomizer = (config, serviceType) => { config.SetEntitySetPageSize("People", 2); }; }; var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}", EmployeeTypeName) }, XPaths = new string[] { "count(//atom:entry)=2", String.Format("//atom:link[@rel='next' and @href='http://host/People/{0}?$skiptoken=3']", EmployeeTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}?$orderby=FullName,ID asc", EmployeeTypeName) }, XPaths = new string[] { "count(//atom:entry)=2", String.Format("//atom:link[@rel='next' and @href=\"http://host/People/{0}?$orderby=FullName,ID%20asc&$skiptoken='Jian%20Li',4\"]", EmployeeTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$orderby={0}/Manager/Name,ID asc", EmployeeTypeName) }, XPaths = new string[] { "count(//atom:entry)=2", String.Format("//atom:link[@rel='next' and @href=\"http://host/People?$orderby={0}/Manager/Name,ID%20asc&$skiptoken=null,5\"]", EmployeeTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}?$expand={1}/DirectReports", EmployeeTypeName, ManagerTypeName) }, XPaths = new string[] { "count(//atom:entry)=4", "count(/atom:feed/atom:entry)=2", String.Format("/atom:feed/atom:link[@rel='next' and @href='http://host/People/{0}?$expand={1}/DirectReports&$skiptoken=3']", EmployeeTypeName, ManagerTypeName), String.Format("/atom:feed/atom:entry/atom:link/adsm:inline/atom:feed/atom:link[@rel='next' and @href='http://host/People(2)/{0}/DirectReports?$skiptoken=4']", ManagerTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/DirectReports", ManagerTypeName) }, XPaths = new string[] { "count(//atom:entry)=4", "count(/atom:feed/atom:entry)=2", String.Format("/atom:feed/atom:link[@rel='next' and @href='http://host/People?$expand={0}/DirectReports&$skiptoken=2']", ManagerTypeName), String.Format("/atom:feed/atom:entry/atom:link/adsm:inline/atom:feed/atom:link[@rel='next' and @href='http://host/People(2)/{0}/DirectReports?$skiptoken=4']", ManagerTypeName) }, Version = testVersion, } }; try { SendRequestAndVerifyXPaths(testCases); } finally { foreach (var service in services) { service.PageSizeCustomizer = null; }; } }
public void DerivedProperty_OpenAndDeclaredPropertyWithSameName() { var metadata = GetModel(true /*openType*/, false /*namedStreams*/, metadataModifier: (m) => { var fullNameProperty = new ResourceProperty("FullName", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string))) { CanReflectOnInstanceTypeProperty = false }; m.GetResourceType("CustomerType").AddProperty(fullNameProperty); }); var serviceWithOpenTypes = new DSPUnitTestServiceDefinition(metadata, DSPDataProviderKind.CustomProvider, GetDefaultData(metadata)); var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { Services = new DSPUnitTestServiceDefinition[] { serviceWithOpenTypes }, RequestUris = new string[] { String.Format("/People?$select=ID,{0}/FullName", EmployeeTypeName) }, // project full name for employees XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID' and local-name()!=FullName])=0", // only ID and FullName properties must be projected for all entries String.Format("count(/atom:feed/atom:entry[atom:category/@term!='#{0}' and atom:category/@term!='#{1}']/atom:content/adsm:properties[count(*)!=1])=0", EmployeeTypeName, ManagerTypeName), // People and Customer should have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category/@term!='#{0}' and atom:category/@term!='#{1}']/atom:content/adsm:properties/*[local-name()!='ID'])=0", EmployeeTypeName, ManagerTypeName), // People and Customershould have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='3{1}']]/atom:content/adsm:properties[count(*)!=2])=0", EmployeeTypeName, ManagerTypeName), // Employee and Manager should have only 2 properties i.e. ID and FullName }, Version = testVersion, }, new DerivedPropertyTestCase() { Services = new DSPUnitTestServiceDefinition[] { serviceWithOpenTypes }, RequestUris = new string[] { "/People?$select=ID,FullName" }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID' and local-name()!=FullName])=0", // all entries should have FullName and ID projected out "count(/atom:feed/atom:entry/atom:content/adsm:properties[count(*)!=2])=0", // all entries should have only 2 properties }, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedPropertyFilterTests() { var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$filter={0}/Manager/Name eq 'Shyam'", EmployeeTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=2", "/atom:feed/atom:entry[atom:id='http://host/People(2)']", "/atom:feed/atom:entry[atom:id='http://host/People(6)']" }, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases); }
public void FilterSingleEntityWithTypeIdentifier() { string xPath = "/atom:entry[atom:category/@term='#" + ManagerTypeName + "' and atom:id='http://host/People(2)' and atom:content/adsm:properties/ads:ID='2']"; DerivedPropertyTestCase[] testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}", ManagerTypeName), String.Format("/People(2)/{0}", EmployeeTypeName), String.Format("/People(2)/{0}", PeopleTypeName) }, XPaths = new string[] { String.Format("count(/atom:entry/atom:category[@term='#{0}'])=1", ManagerTypeName), xPath }, Version = new ServiceVersions(), MinProtocolVersion = ODataProtocolVersion.V4, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}(2)", ManagerTypeName), String.Format("/People/{0}(2)", EmployeeTypeName), String.Format("/People/{0}(2)", PeopleTypeName) }, XPaths = new string[] { String.Format("count(/atom:entry/atom:category[@term='#{0}'])=1", ManagerTypeName), xPath }, Version = new ServiceVersions(), }, }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedPropertyProjectionTests() { var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select={0}/ID", ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(//atom:entry[atom:category/@term!='#{0}']/adsm:properties[count(*)!=0])=0", ManagerTypeName), // non-manager type should have 0 properties projected String.Format("count(//atom:entry[atom:category/@term='#{0}']/adsm:properties[count(*)!=1])=0", ManagerTypeName), // Manager types should have only one property projected String.Format("count(//atom:entry[atom:category/@term='#{0}']/adsm:properties/*[local-name()!='ID'])=0", ManagerTypeName), // Manager types should have only ID property projected }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID&$expand={0}/Manager", EmployeeTypeName) }, // all the employees must have the Manager link property XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(//adsm:properties/*[local-name()!='ID'])!=0", // only ID properties are projected for all entries "count(//atom:entry[atom:category/@term='#AstoriaUnitTests.Tests.People']/atom:link[@rel!=edit])=0", // people type should only have edit links String.Format("count(//atom:entry[atom:category/@term='#{0}' or atom:category/@term='#{1}']/atom:link)>15", EmployeeTypeName, ManagerTypeName) // there should be 5 employee or manager types with edit and manager navigation and association links }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID&$expand={0}/Manager", ManagerTypeName) }, // all the managers must have the Manager link property XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(//adsm:properties/*[local-name()!='ID'])!=0", // only ID properties are projected for all entries "count(//atom:entry/atom:link[@title='Manager'])>4", // Total number of manager links in the entire payload must be 4 String.Format("count(//atom:entry[atom:category/@term='#{0}']/atom:link[@title='Manager'])>4", ManagerTypeName) // there should be 2 manager types with manager navigation and association links }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID&$expand={0}/Manager", EmployeeTypeName) }, // all the employees must have the Manager property expanded XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID'])=0", // only ID properties are projected for all entries "count(/atom:feed/atom:entry[atom:category/@term='#AstoriaUnitTests.Tests.People']/atom:link[@rel!=edit])=0", // people type should only have edit links String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}' or atom:category/@term='#{1}']/atom:link)=15", EmployeeTypeName, ManagerTypeName), // there should be 5 employee or manager types with edit and manager links String.Format("count(//atom:link[@title='Manager']/adsm:inline)=5") // all the manager links must be expanded }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID&$expand={0}/Manager($select=Name)", EmployeeTypeName) }, // all the employees must have the Manager property expanded XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID'])=0", // only ID properties are projected for all entries "count(/atom:feed/atom:entry[atom:category/@term='#AstoriaUnitTests.Tests.People']/atom:link[@rel!=edit])=0", // people type should only have edit links String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}' or atom:category/@term='#{1}']/atom:link)=15", EmployeeTypeName, ManagerTypeName), // there should be 5 employee or manager types with edit and manager links String.Format("count(//atom:link[@title='Manager']/adsm:inline)=5", EmployeeTypeName, ManagerTypeName), // all the manager links must be expanded "count(//adsm:inline/atom:entry/atom:content/adsm:properties/*[local-name()!='Name'])=0", // expanded entries should have only property }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/FullName", EmployeeTypeName) }, // project full name for employees XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID' and local-name()!=FullName])=0", // only ID and FullName properties must be projected for all entries String.Format("count(/atom:feed/atom:entry[atom:category/@term!='#{0}' and atom:category/@term!='#{1}']/atom:content/adsm:properties[count(*)!=1])=0", EmployeeTypeName, ManagerTypeName), // People and Customer should have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category/@term!='#{0}' and atom:category/@term!='#{1}']/atom:content/adsm:properties/*[local-name()!='ID'])=0", EmployeeTypeName, ManagerTypeName), // People and Customershould have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='#{1}']]/atom:content/adsm:properties[count(*)!=2])=0", EmployeeTypeName, ManagerTypeName), // Employee and Manager should have only 2 properties i.e. ID and FullName }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/FullName,{1}/FullName", EmployeeTypeName, CustomerTypeName) }, // project full name for employees and customer XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID' and local-name()!=FullName])=0", // only ID and FullName properties must be projected for all entries String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:content/adsm:properties[count(*)!=1])=0", PeopleTypeName), // People should have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:content/adsm:properties/*[local-name()!='ID'])=0", PeopleTypeName), // People should have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='3{1}' or @term='3{2}']]/atom:content/adsm:properties[count(*)!=2])=0", EmployeeTypeName, ManagerTypeName, CustomerTypeName), // Employee,Manager and Customer should have only 2 properties i.e. ID and FullName }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/FullName,{1}/FullName", ManagerTypeName, CustomerTypeName) }, // project full name for manager and customer types XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID' and local-name()!=FullName])=0", // only ID and FullName properties must be projected for all entries String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='#{1}']]/atom:content/adsm:properties[count(*)!=1])=0", PeopleTypeName, EmployeeTypeName), // People and employee should have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='#{1}']]/atom:content/adsm:properties/*[local-name()!='ID'])=0", PeopleTypeName, EmployeeTypeName), // People and employee should have only one property i.e. ID String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='#{1}']]/atom:content/adsm:properties[count(*)!=2])=0", ManagerTypeName, CustomerTypeName), // Manager and Customer should have only 2 properties i.e. ID and FullName }, Version = testVersion, }, }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedPropertyOrderByTests() { var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$orderby={0}/Manager/Name", EmployeeTypeName) }, XPaths = new string[] { "/atom:feed/atom:entry[position()=1 and atom:id='http://host/People(1)']", "/atom:feed/atom:entry[position()=2 and atom:id='http://host/People(5)']", "/atom:feed/atom:entry[position()=3 and atom:id='http://host/People(7)']", "/atom:feed/atom:entry[position()=4 and atom:id='http://host/People(3)']", "/atom:feed/atom:entry[position()=5 and atom:id='http://host/People(4)']", "/atom:feed/atom:entry[position()=6 and atom:id='http://host/People(2)']", "/atom:feed/atom:entry[position()=7 and atom:id='http://host/People(6)']", }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}?$orderby={1}/Manager/Name", EmployeeTypeName, ManagerTypeName), }, XPaths = new string[] { "/atom:feed/atom:entry[position()=1 and atom:id='http://host/People(3)']", "/atom:feed/atom:entry[position()=2 and atom:id='http://host/People(4)']", "/atom:feed/atom:entry[position()=3 and atom:id='http://host/People(5)']", "/atom:feed/atom:entry[position()=4 and atom:id='http://host/People(6)']", "/atom:feed/atom:entry[position()=5 and atom:id='http://host/People(2)']", }, Version = testVersion, }, }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedPropertyExpandTest() { var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/Manager", EmployeeTypeName), String.Format("/People?$expand={0}/Manager,{1}/Manager", EmployeeTypeName, ManagerTypeName), String.Format("/People?$expand={0}/Manager,{1}/Manager", ManagerTypeName, EmployeeTypeName), String.Format("/People?$expand={0}/Manager", EmployeeTypeName)}, // all the employees must have the Manager property expanded XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='Manager']/adsm:inline)=3", EmployeeTypeName), String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='Manager']/adsm:inline)=2", ManagerTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/Manager", ManagerTypeName) }, // all the managers must have the Manager property expanded XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='Manager']/adsm:inline)=2", ManagerTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/DirectReports", ManagerTypeName) }, // all the managers must have the DirectReports property expanded XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='DirectReports']/adsm:inline/atom:feed)=2", ManagerTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/Manager,{1}/DirectReports", EmployeeTypeName, ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:link[@title='Manager']/adsm:inline)=5", String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='DirectReports']/adsm:inline/atom:feed)=2", ManagerTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/DirectReports($expand={1}/Manager,{0}/DirectReports)", ManagerTypeName, EmployeeTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:link[@title='Manager']/adsm:inline)=0", String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='DirectReports']/adsm:inline/atom:feed)=2", ManagerTypeName), String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='DirectReports']/adsm:inline/atom:feed/atom:entry/atom:link[@title='Manager'])>4", ManagerTypeName), String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@title='DirectReports']/adsm:inline/atom:feed/atom:entry/atom:link[@title='DirectReports']/adsm:inline)=1", ManagerTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/Address", EmployeeTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}' or atom:category/@term='#{1}']/atom:link[@title='Address']/adsm:inline)=5", EmployeeTypeName, ManagerTypeName), // all the employees must have the address property expanded String.Format("count(/atom:feed/atom:entry[atom:category/@term!='#{0}' and atom:category/@term!='#{1}']/atom:link[@title='Address']/adsm:inline)=0", EmployeeTypeName, ManagerTypeName), // none employee should not have address expanded }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$expand={0}/Address, {1}/Address", EmployeeTypeName, CustomerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='#{1}']]/atom:link[@title='Address']/adsm:inline/atom:entry/atom:category[@term='#{2}'])=5", EmployeeTypeName, ManagerTypeName, EmployeeAddressTypeName), // all the employees must have the address property expanded String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}']]/atom:link[@title='Address']/adsm:inline/atom:entry/atom:category[@term='#{1}'])=1", CustomerTypeName, CustomerAddressTypeName), // all the customers must have the address property expanded String.Format("count(/atom:feed/atom:entry[atom:category[@term!='#{0}' and @term!='#{1}' and @term!='#{2}']]/atom:link[@title='Address']/adsm:inline)=0", EmployeeTypeName, ManagerTypeName, CustomerTypeName), // none employees and customers should not have address expanded }, Version = testVersion, }, }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedNavigationPropertyTests() { var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(3)/{0}/Manager", EmployeeTypeName), String.Format("/People(3)/{0}/Manager/{1}", EmployeeTypeName, ManagerTypeName) }, XPaths = GetLinks( GetLinksForPeopleEntity("2", ManagerTypeName), "count(/atom:entry)=1", "/atom:entry[atom:category/@term='#" + ManagerTypeName + "' and contains(atom:id, 'People(2)') and atom:content/adsm:properties/ads:ID='2']", "count(/atom:entry/atom:link)=7", "/atom:entry/atom:link[@rel='edit' and contains(@href, 'People(2)')]"), Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(5)/{0}/DirectReports", ManagerTypeName) }, XPaths = GetLinks( GetLinksForPeopleEntity("2", ManagerTypeName), "count(/atom:feed/atom:entry)=2", string.Format("/atom:feed[atom:id='http://host/People(5)/{0}/DirectReports']", ManagerTypeName), "count(/atom:feed/atom:entry/atom:link)=12", // Andy has edit, Manager, DR and address link, Marcelo has edit, Manager, Address links "/atom:feed/atom:entry/atom:link[@rel='edit' and contains(@href, 'People(2)')]", // BUG BUG : the title must be manager, since the instance is manager type String.Format("/atom:feed/atom:entry" + ManagerNavigationLinkXPath, "People(6)", EmployeeTypeName), "/atom:feed/atom:entry/atom:link[@rel='edit' and contains(@href, 'People(6)')]" ), Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(5)/{0}/DirectReports/{0}", ManagerTypeName) }, XPaths = GetLinks( GetLinksForPeopleEntity("2", ManagerTypeName), "count(/atom:feed/atom:entry)=1", String.Format("/atom:feed[atom:id='http://host/People(5)/{0}/DirectReports/{0}']", ManagerTypeName), "count(/atom:feed/atom:entry/atom:link)=7", "/atom:feed/atom:entry/atom:link[@rel='edit' and contains(@href,'People(2)')]" // BUG BUG : In the above case, its writes out employee, but now its writes manager ), Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}/DirectReports(3)", ManagerTypeName), String.Format("/People(2)/{0}/DirectReports(3)/{1}", ManagerTypeName, EmployeeTypeName), String.Format("/People(2)/{0}/DirectReports/{1}(3)", ManagerTypeName, EmployeeTypeName) }, XPaths = new string[] { "count(/atom:entry)=1", "/atom:entry[atom:category/@term='#" + EmployeeTypeName + "' and atom:id='http://host/People(3)' and atom:content/adsm:properties/ads:ID='3']", "count(/atom:entry/atom:link)=5", "/atom:entry/atom:link[@rel='edit' and contains(@href,'People(3)')]", String.Format("/atom:entry" + ManagerNavigationLinkXPath, "People(3)", EmployeeTypeName) }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(3)/{0}/DirectReports", ManagerTypeName) }, XPaths = new string[] { "count(//atom:entry)=0" }, Version = testVersion, } }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedPrimitivePropertyTests() { var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}/FullName", EmployeeTypeName), String.Format("/People(2)/{0}/FullName", ManagerTypeName) }, XPaths = new string[] { "count(/adsm:value[text()='Andy Conrad'])=1" }, MinProtocolVersion = ODataProtocolVersion.V4, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}(2)/FullName", EmployeeTypeName), String.Format("/People/{0}(2)/FullName", ManagerTypeName) }, XPaths = new string[] { "count(/adsm:value[text()='Andy Conrad'])=1" }, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(2)/{0}/Name", PeopleTypeName) }, XPaths = new string[] { "count(/adsm:value[text()='Andy'])=1" }, MinProtocolVersion = ODataProtocolVersion.V4, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People/{0}(2)/Name", PeopleTypeName) }, XPaths = new string[] { "count(/adsm:value[text()='Andy'])=1" }, }, }; // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight SendRequestAndVerifyXPaths(testCases, formats: new string[] { UnitTestsUtil.MimeApplicationXml }); }
public void DerivedPropertyDeleteTests() { var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People(3)/{0}", EmployeeTypeName) }, HttpMethods = new string[] { "DELETE"}, StatusCode = 204, VerifyXPathsByQuery = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string [] { "/People" }, XPaths = new string[] { "count(/atom:feed/atom:entry)=6" } } }, MinProtocolVersion = ODataProtocolVersion.V4, } }; SendRequestAndVerifyXPaths(testCases, formats: new string[] { "application/atom+xml,application/xml" }); }
public void DerivedPropertyFilterTestsWithAnyAll() { var testVersion = new ServiceVersions(); var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$filter={0}/DirectReports/{0}/any()", ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=1", "/atom:feed/atom:entry[atom:id='http://host/People(5)']", }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$filter={0}/DirectReports/{0}/any(m: m/DirectReports/{0}/any() eq false)", ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=1", "/atom:feed/atom:entry[atom:id='http://host/People(5)']", }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$filter={0}/DirectReports/{0}/any(m: m/DirectReports/{0}/any() eq false and not($it/{0}/DirectReports/all(dr: isof(dr, '{0}'))))", ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=1", "/atom:feed/atom:entry[atom:id='http://host/People(5)']", }, Version = testVersion, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$filter={1}/Manager/DirectReports/{0}/any(m: m/DirectReports/{0}/any())", ManagerTypeName, EmployeeTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=0", }, Version = testVersion, }, }; SendRequestAndVerifyXPaths(testCases); }
public void DerivedNamedStreamPropertyTests() { var testVersion = new ServiceVersions(); var namedStreamService = GetUnitTestServiceDefinition(DSPDataProviderKind.CustomProvider, false, true); var namedStreamServiceWithSDP = GetUnitTestServiceDefinition(DSPDataProviderKind.CustomProvider, false, true); namedStreamServiceWithSDP.PageSizeCustomizer = (config, serviceType) => { config.SetEntitySetPageSize("People", 2); }; var photoLinkRelValue = "http://docs.oasis-open.org/odata/ns/edit-media/Photo"; var testCases = new DerivedPropertyTestCase[] { new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select={0}/Photo", ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + 2, String.Format("//atom:link[@rel='next' and @href='http://host/People?$select={0}/Photo&$skiptoken=2']", ManagerTypeName), }, Version = testVersion, Services = new DSPUnitTestServiceDefinition[] { namedStreamServiceWithSDP }, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select={0}/Photo", ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, String.Format("count(//atom:entry/adsm:properties[count(*)!=0])=0", ManagerTypeName), // none of the entries should have the any properties serialized String.Format("count(//atom:entry[atom:category/@term='#{0}']/atom:link[@rel='{1}'])=2", ManagerTypeName, photoLinkRelValue), // Manager types should have named streams link serialized String.Format("count(//atom:entry[atom:category/@term!='#{0}']/atom:link[@rel='{1}'])=0", ManagerTypeName, photoLinkRelValue), // Non manager types should not have any named streams link serialized }, Version = testVersion, Services = new DSPUnitTestServiceDefinition[] { namedStreamService }, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/Photo,{1}/Photo", CustomerTypeName, EmployeeTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=2", String.Format("//atom:link[@rel='next' and @href='http://host/People?$select=ID,{0}/Photo,{1}/Photo&$skiptoken=2']", CustomerTypeName, EmployeeTypeName), }, Version = testVersion, Services = new DSPUnitTestServiceDefinition[] { namedStreamServiceWithSDP }, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/Photo,{1}/Photo", CustomerTypeName, EmployeeTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID'])=0", // only ID properties are projected for all entries String.Format("count(/atom:feed/atom:entry[atom:category/@term='#{0}']/atom:link[@rel='{1}'])=0", PeopleTypeName, photoLinkRelValue), // people type should not have the named stream link serialized String.Format("count(/atom:feed/atom:entry[atom:category/@term!='#{0}']/atom:link[@rel='{1}'])={2}", PeopleTypeName, photoLinkRelValue, PeopleSetCount - 1), // all non-people should have the named stream link serialized }, Version = testVersion, Services = new DSPUnitTestServiceDefinition[] { namedStreamService }, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/Photo,{1}/Photo", CustomerTypeName, ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=2", String.Format("//atom:link[@rel='next' and @href='http://host/People?$select=ID,{0}/Photo,{1}/Photo&$skiptoken=2']", CustomerTypeName, ManagerTypeName), }, Version = testVersion, Services = new DSPUnitTestServiceDefinition[] { namedStreamServiceWithSDP }, }, new DerivedPropertyTestCase() { RequestUris = new string[] { String.Format("/People?$select=ID,{0}/Photo,{1}/Photo", CustomerTypeName, ManagerTypeName) }, XPaths = new string[] { "count(/atom:feed/atom:entry)=" + PeopleSetCount, "count(/atom:feed/atom:entry/atom:content/adsm:properties/*[local-name()!='ID'])=0", // only ID properties are projected for all entries String.Format("count(/atom:feed/atom:entry[atom:category[@term='#{0}' or @term='3{1}']]/atom:link[@rel='{2}'])=0", PeopleTypeName, EmployeeTypeName, photoLinkRelValue), // people and employee type should not have the named stream link serialized String.Format("count(/atom:feed/atom:entry[atom:category[@term!='{0}' and @term!='{1}']]/atom:link[@rel='{2}'])=3", PeopleTypeName, EmployeeTypeName, photoLinkRelValue), // all non-people should have the named stream link serialized }, Version = testVersion, Services = new DSPUnitTestServiceDefinition[] { namedStreamService }, }, }; SendRequestAndVerifyXPaths(testCases); }
private static void SendRequestAndVerifyXPaths(DerivedPropertyTestCase[] testCases, string[] formats = null, PayloadBuilder[] payloads = null) { var version3 = new[] { ODataProtocolVersion.V4 }; test.TestUtil.RunCombinations(testCases, (testCase) => { test.TestUtil.RunCombinations( testCase.Services ?? services, version3, testCase.HttpMethods, testCase.RequestUris, formats ?? UnitTestsUtil.ResponseFormats, payloads ?? new PayloadBuilder[1] { null }, version3, version3, (service, protocolVersion, httpMethod, requestUri, format, payload, requestDSV, requestMDSV) => { // Currently, IUpdatable is not implemented for ReflectionProvider, hence skipping it for now if (httpMethod != "GET" && service.ProviderKind == DSPDataProviderKind.Reflection) { return; } if (testCase.MinProtocolVersion > protocolVersion) { return; } // If the MPV is V2, we need to ignore requests with request DSV or MDSV greater than v2 if (requestDSV > protocolVersion || requestMDSV > protocolVersion) { return; } JsonToAtomUtil jsonToAtomUtil = new JsonToAtomUtil(service.Metadata); using (OpenWebDataServiceHelper.MaxProtocolVersion.Restore()) using (TestWebRequest request = service.CreateForInProcess()) { OpenWebDataServiceHelper.MaxProtocolVersion.Value = protocolVersion; request.StartService(); request.HttpMethod = httpMethod; request.RequestUriString = requestUri; request.Accept = format; request.RequestVersion = new ServiceVersion(requestDSV).ToString(); request.RequestMaxVersion = new ServiceVersion(requestMDSV).ToString(); if (payload != null) { request.RequestContentType = format; request.SetRequestStreamAsText(PayloadGenerator.Generate(payload, format)); } IDisposable dispose = null; if (httpMethod != "GET") { dispose = service.CreateChangeScope(GetDefaultData(service.Metadata)); } try { Exception exception = System.Data.Test.Astoria.TestUtil.RunCatching(request.SendRequest); if (IsValidScenario(request, protocolVersion, testCase.Version, new ServiceVersion(requestDSV), new ServiceVersion(requestMDSV), exception)) { if (testCase.XPaths != null) { var xPaths = testCase.XPaths; UnitTestsUtil.VerifyXPaths(UnitTestsUtil.GetResponseAsAtom(request, jsonToAtomUtil), xPaths); } Assert.AreEqual(testCase.StatusCode, request.ResponseStatusCode, "The status code is not as expected"); if (testCase.VerifyXPathsByQuery != null) { foreach (var queryTestCase in testCase.VerifyXPathsByQuery) foreach (var queryUri in queryTestCase.RequestUris) { request.RequestUriString = queryUri; request.HttpMethod = "GET"; request.Accept = format; request.RequestMaxVersion = "4.0"; exception = test.TestUtil.RunCatching(request.SendRequest); Assert.IsNull(exception, "No exception expected, but exception was thrown"); UnitTestsUtil.VerifyXPaths(UnitTestsUtil.GetResponseAsAtom(request, jsonToAtomUtil), queryTestCase.XPaths); } } } } finally { if (dispose != null) dispose.Dispose(); } } }); }); }