public ServiceVersions(ServiceVersions source) { if (source != null) { this.MinRequestDSV = source.MinRequestDSV; this.MinRequestMDSV = source.MinRequestMDSV; this.ResponseDSV = source.ResponseDSV; } }
public static ServiceVersions Override(ServiceVersions a, ServiceVersions b) { if (a == null) { return(b); } if (b == null) { return(a); } ServiceVersions result = new ServiceVersions(); result.MinRequestDSV = b.MinRequestDSV ?? a.MinRequestDSV; result.MinRequestMDSV = b.MinRequestMDSV ?? a.MinRequestMDSV; result.ResponseDSV = b.ResponseDSV ?? a.ResponseDSV; return(result); }
public static ServiceVersions Combine(ServiceVersions a, ServiceVersions b) { if (a == null) { return(b); } if (b == null) { return(a); } ServiceVersions result = new ServiceVersions(); result.MinRequestDSV = ServiceVersion.Combine(a.MinRequestDSV, b.MinRequestDSV); result.MinRequestMDSV = ServiceVersion.Combine(a.MinRequestMDSV, b.MinRequestMDSV); result.ResponseDSV = ServiceVersion.Combine(a.ResponseDSV, b.ResponseDSV); return(result); }
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 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); }
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 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 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 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 static ServiceVersions Combine(ServiceVersions a, ServiceVersions b) { if (a == null) return b; if (b == null) return a; ServiceVersions result = new ServiceVersions(); result.MinRequestDSV = ServiceVersion.Combine(a.MinRequestDSV, b.MinRequestDSV); result.MinRequestMDSV = ServiceVersion.Combine(a.MinRequestMDSV, b.MinRequestMDSV); result.ResponseDSV = ServiceVersion.Combine(a.ResponseDSV, b.ResponseDSV); return result; }
public static void SetPUTPATCHVersions(this RequestDescription requestDescription, ServiceVersions versions) { requestDescription.SetAnnotation(PUTMERGEVersionsAnnotationName, versions); }
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 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 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); }
private static bool IsValidScenario(TestWebRequest request, ODataProtocolVersion protocolVersion, ServiceVersions versions, ServiceVersion requestDSV, ServiceVersion requestMDSV, Exception exception) { // figure out the default values of the version if they are null if (requestDSV == null && requestMDSV != null) { requestDSV = requestMDSV.Version > 20 ? requestMDSV : new ServiceVersion(40); } if (exception != null) { Assert.AreEqual(400, request.ResponseStatusCode, "Expecting bad request"); List<string> expectedErrorMessages = new List<string>(); if (requestDSV != null && requestDSV.Version < versions.MinRequestDSV.Version) { expectedErrorMessages.Add(DataServicesResourceUtil.GetString("DataService_DSVTooLow", requestDSV.ToString(), versions.MinRequestDSV.Version / 10, versions.MinRequestDSV.Version % 10)); } if (requestMDSV != null && requestMDSV.Version < versions.MinRequestMDSV.Version) { expectedErrorMessages.Add(DataServicesResourceUtil.GetString("DataService_MaxDSVTooLow", requestMDSV.ToString(), versions.MinRequestMDSV.Version / 10, versions.MinRequestMDSV.Version % 10)); } // Since enableRelationshipLinks is true, the response will be 3.0 if the MPV is set to 3.0. For V1/V2 servers, this setting is ignored if (protocolVersion == ODataProtocolVersion.V4 && requestMDSV != null && requestMDSV.ToProtocolVersion() < protocolVersion) { expectedErrorMessages.Add(DataServicesResourceUtil.GetString("DataService_MaxDSVTooLow", requestMDSV.ToString(), 4, 0)); } if (expectedErrorMessages.Count != 0) { Assert.IsTrue(expectedErrorMessages.Contains(exception.InnerException.Message), "Didn't find the expected error message"); } else { Assert.Fail("Exception not expected, but exception was thrown"); } return false; } Assert.IsTrue(requestDSV == null || requestDSV.Version >= versions.MinRequestDSV.Version, "Request DSV should be equal or greater than the min required DSV"); Assert.IsTrue(requestMDSV == null || requestMDSV.Version >= versions.MinRequestMDSV.Version, "Request MDSV should be equal or greater than the min required MDSV"); return true; }
public static void SetPOSTVersions(this RequestDescription requestDescription, ServiceVersions versions) { requestDescription.SetAnnotation(POSTVersionsAnnotationName, versions); }
public static ServiceVersions Override(ServiceVersions a, ServiceVersions b) { if (a == null) return b; if (b == null) return a; ServiceVersions result = new ServiceVersions(); result.MinRequestDSV = b.MinRequestDSV ?? a.MinRequestDSV; result.MinRequestMDSV = b.MinRequestMDSV ?? a.MinRequestMDSV; result.ResponseDSV = b.ResponseDSV ?? a.ResponseDSV; return result; }
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 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); }