Example #1
0
 public ServiceVersions(ServiceVersions source)
 {
     if (source != null)
     {
         this.MinRequestDSV  = source.MinRequestDSV;
         this.MinRequestMDSV = source.MinRequestMDSV;
         this.ResponseDSV    = source.ResponseDSV;
     }
 }
Example #2
0
        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);
        }
Example #3
0
        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;
                };
            }
        }
Example #10
0
        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;
        }
Example #11
0
 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;
        }
Example #16
0
 public static void SetPOSTVersions(this RequestDescription requestDescription, ServiceVersions versions)
 { requestDescription.SetAnnotation(POSTVersionsAnnotationName, versions); }
Example #17
0
 public static void SetPUTPATCHVersions(this RequestDescription requestDescription, ServiceVersions versions)
 { requestDescription.SetAnnotation(PUTMERGEVersionsAnnotationName, versions); }
Example #18
0
        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);
        }
Example #21
0
 public static void SetPOSTVersions(this RequestDescription requestDescription, ServiceVersions versions)
 {
     requestDescription.SetAnnotation(POSTVersionsAnnotationName, versions);
 }
Example #22
0
 public ServiceVersions(ServiceVersions source)
 {
     if (source != null)
     {
         this.MinRequestDSV = source.MinRequestDSV;
         this.MinRequestMDSV = source.MinRequestMDSV;
         this.ResponseDSV = source.ResponseDSV;
     }
 }