Example #1
0
 internal bool CompareProperties(PayloadObject payloadObject, object element, bool throwOnFailure)
 {
     // Verify resource properties and navigation
     foreach (PayloadProperty property in payloadObject.PayloadProperties)
     {
         if (property is PayloadComplexProperty)
         {
             PayloadComplexProperty payloadProperty = (PayloadComplexProperty)property;
             if (!this.CompareComplexType(payloadProperty, element, true))
             {
                 if (throwOnFailure)
                 {
                     throw new TestFailedException("Value for complex property '" + property.Name + "' does not batch baseline");
                 }
                 return(false);
             }
         }
         else if (property is PayloadSimpleProperty)
         {
             PayloadSimpleProperty payloadProperty = (PayloadSimpleProperty)property;
             if (!this.CompareSimpleType(payloadProperty, element, true))
             {
                 if (throwOnFailure)
                 {
                     throw new TestFailedException("Value for simple property '" + property.Name + "' does not batch baseline");
                 }
                 return(false);
             }
         }
     }
     return(true);
 }
Example #2
0
        internal PayloadComplexProperty parseComplexObject(PayloadObject parent, JSField field)
        {
            PayloadComplexProperty payloadProperty = new PayloadComplexProperty(parent);

            payloadProperty.Name = field.Name;

            JSObject fieldValue = (JSObject)field.GetValue(field);

            FieldInfo[] fieldInfo = fieldValue.GetFields(BindingFlags.Default);

            for (int j = 0; j < fieldInfo.Length; j++)
            {
                JSField currentField = (JSField)fieldInfo[j];

                if (currentField.GetValue(currentField) is JSObject)
                {
                    PayloadComplexProperty payloadComplexProperty = this.parseComplexObject(parent, (JSField)fieldInfo[j]);
                    payloadProperty.PayloadProperties.Add(payloadComplexProperty.Name, payloadComplexProperty);
                }
                else
                {
                    PayloadProperty payloadSimpleProperty = this.parseSimpleObject(parent, (JSField)fieldInfo[j]);
                    payloadProperty.PayloadProperties.Add(payloadSimpleProperty.Name, payloadSimpleProperty);
                }
            }

            return(payloadProperty);
        }
Example #3
0
        internal void CompareObjects(PayloadObject payloadObject, object element)
        {
            bool found;

            foreach (PayloadObject nestedObject in payloadObject.PayloadObjects)
            {
                if (nestedObject.Deferred)
                {
                    // do something
                }
                else if (nestedObject.Reference)
                {
                    object nestedElement = LoadReference(element, nestedObject.Name);

                    //this.CompareUri(referenceObject.Uri, referenceObject.Id, referenceObject.Name, nestedObject.Name);
                    this.CompareProperties(nestedObject, nestedElement, true);
                    this.CompareObjects(nestedObject, nestedElement);
                }
                else
                {
                    // Call load on nested element
                    List <object> enumerableList = LoadCollection(element, nestedObject.Name).OfType <object>().ToList();
                    Compare(enumerableList, nestedObject.PayloadObjects, true);
                }
            }
        }
Example #4
0
        private void VerifyInsertResponse(ResourceType type, PayloadObject inserted, PayloadObject returned)
        {
            // need to 'follow' deferred links to ensure that they're correct
            // doesn't need to match exactly
            AstoriaTestLog.AreEqual(inserted.Type, returned.Type, "Types do not match");

            VerifyProperties(type, inserted, returned, true, (rp => !rp.Facets.ServerGenerated));
        }
Example #5
0
        private void VerifyQueryResponse(ResourceType type, PayloadObject fromInsert, PayloadObject fromQuery)
        {
            bool keyShouldMatch = true;

            if (type.Key.Properties.Any(p => p.Facets.FixedLength))
            {
                foreach (NodeProperty property in type.Key.Properties.Where(p => p.Facets.FixedLength))
                {
                    // this may not always be correct for all types, but it seems to work most of the time;
                    int length;
                    if (property.Facets.MaxSize.HasValue)
                    {
                        length = property.Facets.MaxSize.Value;
                    }
                    else if (property.Type == Clr.Types.Decimal)
                    {
                        length = property.Facets.Precision.Value + property.Facets.Scale.Value;
                    }
                    else
                    {
                        continue;
                    }

                    string value = null;
                    if (fromInsert.PayloadProperties.Any(p => p.Name == property.Name))
                    {
                        value = (fromInsert[property.Name] as PayloadSimpleProperty).Value;
                    }
                    else
                    {
                        value = fromInsert.CustomEpmMappedProperties[property.Name];
                    }

                    if (value != null && value.Length < length)
                    {
                        keyShouldMatch = false;
                    }
                }
            }

            if (keyShouldMatch)
            {
                AstoriaTestLog.AreEqual(fromInsert.AbsoluteUri, fromQuery.AbsoluteUri, "fromInsert.AbsoluteUri != fromQuery.AbsoluteUri", false);
            }
            else
            {
                AstoriaTestLog.IsFalse(fromInsert.AbsoluteUri == fromQuery.AbsoluteUri, "fromInsert.AbsoluteUri == fromQuery.AbsoluteUri, despite fixed-length string");
            }

            // leave it to the concurrency tests to check the more involved etags
            if (!type.Properties.Any(p => p.Facets.ConcurrencyModeFixed && p.Facets.FixedLength))
            {
                AstoriaTestLog.AreEqual(fromInsert.ETag, fromQuery.ETag, "fromInsert.ETag != fromQuery.ETag", false);
            }

            VerifyProperties(type, fromInsert, fromQuery, false, rp => true);
        }
Example #6
0
        internal PayloadObject ParseUriNode(XElement node)
        {
            PayloadObject         po       = new PayloadObject(this);
            PayloadSimpleProperty property = new PayloadSimpleProperty(po);

            property.Value = node.Value;
            property.Name  = node.Name.LocalName;
            po.Name        = node.Name.LocalName;
            po.PayloadProperties.Add(property);
            return(po);
        }
Example #7
0
 protected static bool TryGetSingleObjectFromPayload(CommonPayload payload, out PayloadObject payloadObject)
 {
     List<PayloadObject> list = payload.Resources as List<PayloadObject>;
     if (list == null || list.Count != 1)
     {
         payloadObject = null;
         return false;
     }
     payloadObject = list[0];
     return true;
 }
Example #8
0
        private void Compare(IList <object> baselineObjects, IList <PayloadObject> payloadObjects, bool ignoreOrder)
        {
            AstoriaTestLog.AreEqual(baselineObjects.Count, payloadObjects.Count, "Count of baseline not equal to returned elements.", false);

            for (int position = 0; position < baselineObjects.Count; position++)
            {
                PayloadObject fromPayload  = payloadObjects[position];
                object        fromBaseline = null;

                if (ignoreOrder)
                {
                    foreach (object entity in baselineObjects)
                    {
                        if (this.CompareProperties(fromPayload, entity, false))
                        {
                            fromBaseline = entity;
                            break;
                        }
                    }

                    if (fromBaseline == null)
                    {
                        throw new TestFailedException("Could not find matching entity");
                    }
                    else
                    {
                        baselineObjects.Remove(fromBaseline);
                    }
                }
                else
                {
                    fromBaseline = baselineObjects[position];

                    try
                    {
                        this.CompareProperties(fromPayload, fromBaseline, true);
                    }
                    catch (Exception e)
                    {
                        throw new TestFailedException("Payload properties do not match baseline for entity at position " + position + " in payload", null, null, e);
                    }
                }

                try
                {
                    this.CompareObjects(fromPayload, fromBaseline);
                }
                catch (Exception e)
                {
                    throw new TestFailedException("Payload objects do not match baseline for entity at position " + position + " in payload", null, null, e);
                }
            }
        }
Example #9
0
        private void ParseResults(string payload)
        {
            if (payload == null)
            {
                this.Value = null;
                return;
            }

            try
            {
                document = XDocument.Parse(payload);
            }
            catch (Exception e)
            {
                this.Value = payload;
                return;
            }

            XElement xmlData = document.Root;

            if (xmlData.Name.LocalName == "feed")
            {
                this.Resources = this.ParseFeed(xmlData);
            }
            else if (xmlData.Name.LocalName == "entry")
            {
                this.Resources = this.ParseSingleEntry(xmlData);
            }
            else if (xmlData.Name.LocalName == "links")
            {
                this.Resources = this.ParseLinks(xmlData);
            }
            else if (xmlData.Name.LocalName == "uri")
            {
                this.Resources = new List <PayloadObject>()
                {
                    this.ParseUriNode(xmlData)
                }
            }
            ;
            else
            {
                PayloadObject payloadObject = new PayloadObject(this);
                if (xmlData.HasElements)
                {
                    this.Resources = this.ParseComplexProperty(payloadObject, xmlData);
                }
                else
                {
                    this.Resources = this.ParseSimpleProperty(payloadObject, xmlData);
                }
            }
        }
Example #10
0
        protected static bool TryGetSingleObjectFromPayload(CommonPayload payload, out PayloadObject payloadObject)
        {
            List <PayloadObject> list = payload.Resources as List <PayloadObject>;

            if (list == null || list.Count != 1)
            {
                payloadObject = null;
                return(false);
            }
            payloadObject = list[0];
            return(true);
        }
Example #11
0
        public static KeyExpression ConstructKey(ResourceContainer container, PayloadObject entity)
        {
            Dictionary <string, object> properties = new Dictionary <string, object>();

            ResourceType type = container.BaseType;

            if (entity.Type != type.Namespace + "." + type.Name)
            {
                type = container.ResourceTypes.SingleOrDefault(rt => rt.Namespace + "." + rt.Name == entity.Type);
                if (type == null)
                {
                    AstoriaTestLog.FailAndThrow("Could not find resource type for payload type value: " + entity.Type);
                }
            }

            foreach (ResourceProperty property in type.Properties.OfType <ResourceProperty>())
            {
                if (property.IsNavigation || property.IsComplexType)
                {
                    continue;
                }

                string propertyName = property.Name;
                string valueString;
                if (entity.PayloadProperties.Any(p => p.Name == propertyName))
                {
                    PayloadSimpleProperty simpleProperty = entity[propertyName] as PayloadSimpleProperty;
                    if (simpleProperty == null)
                    {
                        continue;
                    }

                    valueString = simpleProperty.Value;
                }
                else
                {
                    continue;
                }

                object value = CommonPayload.DeserializeStringToObject(valueString, property.Type.ClrType, false, entity.Format);
                if (value is DateTime && entity.Format == SerializationFormatKind.JSON)
                {
                    // TODO: this is because the server will make any JSON datetime into UTC, and currently we always send 'unspecified' values
                    value = new DateTime(((DateTime)value).Ticks, DateTimeKind.Unspecified);
                }

                properties[propertyName] = value;
            }

            return(new KeyExpression(container, type, properties));
        }
Example #12
0
        public static KeyExpression ConstructKey(ResourceContainer container, PayloadObject entity)
        {
            Dictionary<string, object> properties = new Dictionary<string, object>();

            ResourceType type = container.BaseType;
            if (entity.Type != type.Namespace + "." + type.Name)
            {
                type = container.ResourceTypes.SingleOrDefault(rt => rt.Namespace + "." + rt.Name == entity.Type);
                if (type == null)
                    AstoriaTestLog.FailAndThrow("Could not find resource type for payload type value: " + entity.Type);
            }

            foreach (ResourceProperty property in type.Properties.OfType<ResourceProperty>())
            {
                if (property.IsNavigation || property.IsComplexType)
                    continue;

                string propertyName = property.Name;
                string valueString;
                if (entity.PayloadProperties.Any(p => p.Name == propertyName))
                {
                    PayloadSimpleProperty simpleProperty = entity[propertyName] as PayloadSimpleProperty;
                    if (simpleProperty == null)
                        continue;

                    valueString = simpleProperty.Value;
                }
                else
                {
                    continue;
                }

                object value = CommonPayload.DeserializeStringToObject(valueString, property.Type.ClrType, false, entity.Format);
                if (value is DateTime && entity.Format == SerializationFormatKind.JSON)
                {
                    // TODO: this is because the server will make any JSON datetime into UTC, and currently we always send 'unspecified' values
                    value = new DateTime(((DateTime)value).Ticks, DateTimeKind.Unspecified);
                }

                properties[propertyName] = value;
            }

            return new KeyExpression(container, type, properties);
        }
Example #13
0
        internal PayloadSimpleProperty parseSimpleObject(PayloadObject parent, JSField field)
        {
            PayloadSimpleProperty payloadProperty = new PayloadSimpleProperty(parent);

            payloadProperty.Name = field.Name;

            object val = field.GetValue(field);

            if (val is System.DBNull)
            {
                payloadProperty.Value  = null;
                payloadProperty.Type   = null;
                payloadProperty.IsNull = true;
            }
            else
            {
                payloadProperty.Type   = AstoriaUnitTests.Data.TypeData.FindForType(val.GetType()).GetEdmTypeName();
                payloadProperty.Value  = ConvertJsonValue(val);
                payloadProperty.IsNull = false;
            }

            return(payloadProperty);
        }
Example #14
0
        private void ParseResults(string payload)
        {
            if (payload == null)
            {
                this.Value = null;
                return;
            }

            try
            {
                document = XDocument.Parse(payload);
            }
            catch (Exception e)
            {
                this.Value = payload;
                return;
            }

            XElement xmlData = document.Root;

            if (xmlData.Name.LocalName == "feed")
                this.Resources = this.ParseFeed(xmlData);
            else if (xmlData.Name.LocalName == "entry")
                this.Resources = this.ParseSingleEntry(xmlData);
            else if (xmlData.Name.LocalName == "links")
                this.Resources = this.ParseLinks(xmlData);
            else if (xmlData.Name.LocalName == "uri")
                this.Resources = new List<PayloadObject>() { this.ParseUriNode(xmlData) };
            else
            {
                PayloadObject payloadObject = new PayloadObject(this);
                if (xmlData.HasElements)
                    this.Resources = this.ParseComplexProperty(payloadObject, xmlData);
                else
                    this.Resources = this.ParseSimpleProperty(payloadObject, xmlData);
            }
        }
Example #15
0
        internal PayloadComplexProperty ParseComplexProperty(PayloadObject parent, XElement xmlData)
        {
            PayloadComplexProperty payloadProperty = new PayloadComplexProperty(parent);

            payloadProperty.Name = xmlData.Name.LocalName;

            XAttribute nullAttribute = xmlData.Attribute(m + "null");

            if (nullAttribute != null && nullAttribute.Value == "true")
            {
                payloadProperty.IsNull = true;
            }

            XAttribute typeAttribute = xmlData.Attribute(m + "type");

            if (typeAttribute != null)
            {
                payloadProperty.Type = typeAttribute.Value;
            }

            foreach (XElement property in xmlData.Elements())
            {
                PayloadProperty subProperty;
                if (property.HasElements)
                {
                    subProperty = ParseComplexProperty(parent, property);
                }
                else
                {
                    subProperty = ParseSimpleProperty(parent, property);
                }
                payloadProperty.PayloadProperties.Add(subProperty.Name, subProperty);
            }

            return(payloadProperty);
        }
Example #16
0
        internal PayloadSimpleProperty ParseSimpleProperty(PayloadObject parent, XElement xmlData)
        {
            PayloadSimpleProperty payloadProperty = new PayloadSimpleProperty(parent);

            payloadProperty.Name  = xmlData.Name.LocalName;
            payloadProperty.Value = xmlData.Value;

            XAttribute nullAttribute = xmlData.Attribute(m + "null");

            if (nullAttribute != null && nullAttribute.Value == "true")
            {
                payloadProperty.Value  = null;
                payloadProperty.IsNull = true;
            }

            XAttribute typeAttribute = xmlData.Attribute(m + "type");

            if (typeAttribute != null)
            {
                payloadProperty.Type = typeAttribute.Value;
            }

            return(payloadProperty);
        }
Example #17
0
        private void ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty itemProperty, XElement xmlData, PayloadObject payloadObject)
        {
            XElement element = xmlData.Element(atom + itemProperty.ToString().ToLowerInvariant());

            if (element != null)
            {
                var value = element.Value;

                XAttribute nullAttribute = element.Attribute(m + "null");
                if (nullAttribute != null && nullAttribute.Value == "true")
                {
                    value = null;
                }

                payloadObject.SyndicationItemProperties[itemProperty] = value;
            }
        }
Example #18
0
        internal static KeyedResourceInstance CreateKeyedResourceInstanceFromPayloadObject(ResourceContainer container, ResourceType resourceType, PayloadObject payloadObject)
        {
            List <ResourceInstanceProperty> properties    = new List <ResourceInstanceProperty>();
            List <ResourceInstanceProperty> keyProperties = new List <ResourceInstanceProperty>();

            foreach (ResourceProperty property in resourceType.Properties.OfType <ResourceProperty>())
            {
                if (property.IsNavigation)
                {
                    continue;
                }

                if (property.IsComplexType)
                {
                    PayloadComplexProperty fromPayload = payloadObject[property.Name] as PayloadComplexProperty;
                    properties.Add(ConvertComplexPayloadObjectToComplexProperty(property, fromPayload));
                }
                else
                {
                    string stringValue;
                    if (payloadObject.PayloadProperties.Any(p => p.Name == property.Name))
                    {
                        PayloadSimpleProperty fromPayload = payloadObject[property.Name] as PayloadSimpleProperty;
                        stringValue = fromPayload.Value;
                    }
                    else
                    {
                        if (!payloadObject.CustomEpmMappedProperties.TryGetValue(property.Name, out stringValue))
                        {
                            stringValue = null;
                        }
                    }

                    ResourceInstanceProperty newProperty = null;
                    object val = CommonPayload.DeserializeStringToObject(stringValue, property.Type.ClrType, false, payloadObject.Format);
                    newProperty = new ResourceInstanceSimpleProperty(property.Name, new NodeValue(val, property.Type));

                    if (property.PrimaryKey != null)
                    {
                        keyProperties.Add(newProperty);
                    }
                    else
                    {
                        properties.Add(newProperty);
                    }
                }
            }

            ResourceInstanceKey key = new ResourceInstanceKey(container, resourceType, keyProperties.ToArray());

            return(new KeyedResourceInstance(key, properties.ToArray()));
        }
Example #19
0
        private PayloadObject parseJsonObject(JSObject jsObject)
        {
            PayloadObject payloadObject = new PayloadObject(this);

            FieldInfo[] fields = jsObject.GetFields(BindingFlags.Default);

            for (int i = 0; i < fields.Length; i++)
            {
                JSField field = (JSField)fields[i];
                var     value = field.GetValue(field);

                if (value is ArrayObject)
                {
                    PayloadObject payloadNestedParentObject = new PayloadObject(this);
                    payloadNestedParentObject.Name = field.Name;

                    ArrayObject nestedPayloadObjects = (ArrayObject)field.GetValue(field);
                    payloadNestedParentObject.PayloadObjects.AddRange(this.ParseJsonArray(nestedPayloadObjects));

                    foreach (PayloadObject po in payloadNestedParentObject.PayloadObjects)
                    {
                        po.Name = field.Name;
                    }

                    payloadObject.PayloadObjects.Add(payloadNestedParentObject);
                }
                else if (value is JSObject)
                {
                    if (field.Name == "__metadata")
                    {
                        payloadObject.Uri  = this.GetArrayString(field, "uri");
                        payloadObject.Type = this.GetArrayString(field, "type");

                        string etag = this.GetArrayString(field, "etag");
                        if (etag != null)
                        {
                            payloadObject.ETag = etag;
                        }
                    }
                    else
                    {
                        JSField firstChild = this.GetArrayField(field, 0);

                        if (firstChild != null && firstChild.Name == v2JsonResultsField)
                        {
                            PayloadObject payloadNestedParentObject = new PayloadObject(this);
                            payloadNestedParentObject.Name = field.Name;

                            ArrayObject nestedPayloadObjects = (ArrayObject)firstChild.GetValue(firstChild);
                            payloadNestedParentObject.PayloadObjects.AddRange(this.ParseJsonArray(nestedPayloadObjects));

                            foreach (PayloadObject po in payloadNestedParentObject.PayloadObjects)
                            {
                                po.Name = field.Name;
                            }

                            payloadObject.PayloadObjects.Add(payloadNestedParentObject);
                        }
                        else if (firstChild != null && firstChild.Name == "__deferred") // Deferred reference/collection
                        {
                            PayloadObject deferredObject = new PayloadObject(this);
                            deferredObject.Name     = field.Name;
                            deferredObject.Uri      = this.GetArrayString(firstChild, "uri");
                            deferredObject.Deferred = true;

                            payloadObject.PayloadObjects.Add(deferredObject);
                        }
                        else if (firstChild != null && firstChild.Name == "__mediaresource")
                        {
                            PayloadNamedStream stream = new PayloadNamedStream();
                            stream.Name        = field.Name;
                            stream.ContentType = this.GetArrayString(firstChild, "content-type");
                            stream.EditLink    = this.GetArrayString(firstChild, "edit_media");
                            stream.SelfLink    = this.GetArrayString(firstChild, "media_src");
                            stream.ETag        = this.GetArrayString(firstChild, "etag");
                            payloadObject.NamedStreams.Add(stream);
                        }
                        else
                        {
                            JSObject objectValue       = (JSObject)field.GetValue(field);
                            var      objectValueFields = objectValue.GetFields(BindingFlags.Default);
                            if (objectValueFields.Any(f => f.Name == "__metadata" && GetArrayString((JSField)f, "uri") != null))
                            {
                                PayloadObject referencePayloadObject = parseJsonObject(objectValue);
                                referencePayloadObject.Name      = field.Name;
                                referencePayloadObject.Reference = true;

                                payloadObject.PayloadObjects.Add(referencePayloadObject);
                            }
                            else
                            {
                                PayloadComplexProperty payloadProperty = this.parseComplexObject(payloadObject, field);    // Complex object
                                payloadObject.PayloadProperties.Add(payloadProperty);
                            }
                        }
                    }
                }
                else
                {
                    PayloadProperty payloadProperty = this.parseSimpleObject(payloadObject, field);
                    payloadObject.PayloadProperties.Add(payloadProperty);
                }
            }

            return(payloadObject);
        }
Example #20
0
        private void VerifyProperties(ResourceType type, PayloadObject inserted, PayloadObject returned, bool missingInsertPropertiesOk, Func<ResourceProperty, bool> strictEquality)
        {
            List<string> propertyNames = inserted.PayloadProperties.Union(returned.PayloadProperties).Select(p => p.Name).ToList();
            propertyNames.AddRange(inserted.CustomEpmMappedProperties.Keys);
            propertyNames.AddRange(returned.CustomEpmMappedProperties.Keys);
            
            foreach (string propertyName in propertyNames.Distinct())
            {
                PayloadProperty insertedProperty;
                if(inserted.Format == SerializationFormatKind.JSON) //in JSON the first one wins
                    insertedProperty = inserted.PayloadProperties.FirstOrDefault(p => p.Name == propertyName);
                else //in xml the last one wins
                    insertedProperty = inserted.PayloadProperties.LastOrDefault(p => p.Name == propertyName);
                bool insertHadProperty = insertedProperty != null;

                PayloadProperty returnedProperty = returned.PayloadProperties.LastOrDefault(p => p.Name == propertyName); ;
                bool returnedHadProperty = returnedProperty != null;

                ResourceProperty property = type.Properties.OfType<ResourceProperty>().SingleOrDefault(p => p.Name == propertyName);

                if (property == null || !property.Facets.IsDeclaredProperty)
                {
                    if (!type.Facets.IsOpenType)
                    {
                        string error = "included dynamic property '" + propertyName + "' despite '" + type.Name + "' not being an open type";
                        if (insertHadProperty && returnedHadProperty)
                            AstoriaTestLog.FailAndThrow("Both the inserted and returned objects " + error);
                        else if (insertHadProperty)
                            AstoriaTestLog.FailAndThrow("The inserted object " + error);
                        else if (returnedHadProperty)
                            AstoriaTestLog.FailAndThrow("The returned object " + error);
                    }
                    else
                    {
                        if (insertHadProperty && returnedHadProperty)
                        {
                            CompareDynamicPropertyValues(insertedProperty, returnedProperty);
                        }
                        else if (insertHadProperty)
                        {
                            // only acceptable if inserted value was null
                            if (insertedProperty.IsNull)
                                AstoriaTestLog.FailAndThrow("Returned object missing non-null dynamic property '" + propertyName + "'");
                        }
                    }
                }
                else
                {
                    if (property.IsNavigation)
                    {
                        // the insert payload may not specify this property
                        //PayloadObject insertedObject = inserted.PayloadObjects.SingleOrDefault(o => o.Name == property.Name);
                        PayloadObject returnedObject = returned.PayloadObjects.Single(o => o.Name == property.Name);

                        // returned thing should be deferred whether its a reference or not
                        AstoriaTestLog.AreEqual(true, returnedObject.Deferred, "!returnedObject.Deferred", false);

                        // TODO: verify only expected links are present (based on uri and payload values as well)
                    }
                    else
                    {
                        if (insertHadProperty && returnedHadProperty)
                        {
                            try
                            {
                                ComparePropertyValues(property, insertedProperty, returnedProperty, strictEquality(property));
                            }
                            catch (Exception e)
                            {
                                throw new TestFailedException("Value of property '" + property.Name + "' does not match inserted value", null, null, e);
                            }
                        }
                        else if (insertHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Returned object unexpectedly missing declared property '" + propertyName + "'");
                        }
                        else if (returnedHadProperty)
                        {
                            if (missingInsertPropertiesOk)
                                AstoriaTestLog.WriteLineIgnore("Ignoring missing declared property '" + propertyName + "' in insert payload");
                            else
                                AstoriaTestLog.FailAndThrow("Inserted object unexpectedly missing declared property '" + propertyName + "'");
                        }
                    }
                }
            }
        }
Example #21
0
        private void VerifyQueryResponse(ResourceType type, PayloadObject fromInsert, PayloadObject fromQuery)
        {
            bool keyShouldMatch = true;
            if (type.Key.Properties.Any(p => p.Facets.FixedLength))
            {
                foreach (NodeProperty property in type.Key.Properties.Where(p => p.Facets.FixedLength))
                {
                    // this may not always be correct for all types, but it seems to work most of the time;
                    int length;
                    if (property.Facets.MaxSize.HasValue)
                        length = property.Facets.MaxSize.Value;
                    else if (property.Type == Clr.Types.Decimal)
                        length = property.Facets.Precision.Value + property.Facets.Scale.Value;
                    else
                        continue;

                    string value = null;
                    if (fromInsert.PayloadProperties.Any(p => p.Name == property.Name))
                    {
                        value = (fromInsert[property.Name] as PayloadSimpleProperty).Value;
                    }
                    else
                    {
                        value = fromInsert.CustomEpmMappedProperties[property.Name];
                    }

                    if (value != null && value.Length < length)
                        keyShouldMatch = false;
                }
            }

            if (keyShouldMatch)
                AstoriaTestLog.AreEqual(fromInsert.AbsoluteUri, fromQuery.AbsoluteUri, "fromInsert.AbsoluteUri != fromQuery.AbsoluteUri", false);
            else
                AstoriaTestLog.IsFalse(fromInsert.AbsoluteUri == fromQuery.AbsoluteUri, "fromInsert.AbsoluteUri == fromQuery.AbsoluteUri, despite fixed-length string");

            // leave it to the concurrency tests to check the more involved etags
            if (!type.Properties.Any(p => p.Facets.ConcurrencyModeFixed && p.Facets.FixedLength))
                AstoriaTestLog.AreEqual(fromInsert.ETag, fromQuery.ETag, "fromInsert.ETag != fromQuery.ETag", false);

            VerifyProperties(type, fromInsert, fromQuery, false, rp => true);
        }
Example #22
0
        internal PayloadComplexProperty parseComplexObject(PayloadObject parent, JSField field)
        {
            PayloadComplexProperty payloadProperty = new PayloadComplexProperty(parent);
            payloadProperty.Name = field.Name;

            JSObject fieldValue = (JSObject)field.GetValue(field);
            FieldInfo[] fieldInfo = fieldValue.GetFields(BindingFlags.Default);

            for (int j = 0; j < fieldInfo.Length; j++)
            {
                JSField currentField = (JSField)fieldInfo[j];

                if (currentField.GetValue(currentField) is JSObject)
                {
                    PayloadComplexProperty payloadComplexProperty = this.parseComplexObject(parent, (JSField)fieldInfo[j]);
                    payloadProperty.PayloadProperties.Add(payloadComplexProperty.Name, payloadComplexProperty);
                }
                else
                {
                    PayloadProperty payloadSimpleProperty = this.parseSimpleObject(parent, (JSField)fieldInfo[j]);
                    payloadProperty.PayloadProperties.Add(payloadSimpleProperty.Name, payloadSimpleProperty);
                }
            }

            return payloadProperty;
        }
Example #23
0
        private PayloadObject parseJsonObject(JSObject jsObject)
        {
            PayloadObject payloadObject = new PayloadObject(this);

            FieldInfo[] fields = jsObject.GetFields(BindingFlags.Default);

            for (int i = 0; i < fields.Length; i++)
            {
                JSField field = (JSField)fields[i];
                var value = field.GetValue(field);

                if (value is ArrayObject)
                {
                    PayloadObject payloadNestedParentObject = new PayloadObject(this);
                    payloadNestedParentObject.Name = field.Name;

                    ArrayObject nestedPayloadObjects = (ArrayObject)field.GetValue(field);
                    payloadNestedParentObject.PayloadObjects.AddRange(this.ParseJsonArray(nestedPayloadObjects));

                    foreach (PayloadObject po in payloadNestedParentObject.PayloadObjects)
                    {
                        po.Name = field.Name;
                    }

                    payloadObject.PayloadObjects.Add(payloadNestedParentObject);
                }
                else if (value is JSObject)
                {
                    if (field.Name == "__metadata")
                    {
                        payloadObject.Uri = this.GetArrayString(field, "uri");
                        payloadObject.Type = this.GetArrayString(field, "type");

                        string etag = this.GetArrayString(field, "etag");
                        if (etag != null)
                        {
                            payloadObject.ETag = etag;
                        }
                    }
                    else
                    {
                        JSField firstChild = this.GetArrayField(field, 0);

                        if (firstChild != null && firstChild.Name == v2JsonResultsField)
                        {
                            PayloadObject payloadNestedParentObject = new PayloadObject(this);
                            payloadNestedParentObject.Name = field.Name;

                            ArrayObject nestedPayloadObjects = (ArrayObject)firstChild.GetValue(firstChild);
                            payloadNestedParentObject.PayloadObjects.AddRange(this.ParseJsonArray(nestedPayloadObjects));

                            foreach (PayloadObject po in payloadNestedParentObject.PayloadObjects)
                            {
                                po.Name = field.Name;
                            }

                            payloadObject.PayloadObjects.Add(payloadNestedParentObject);
                        }
                        else if (firstChild != null && firstChild.Name == "__deferred") // Deferred reference/collection
                        {
                            PayloadObject deferredObject = new PayloadObject(this);
                            deferredObject.Name = field.Name;
                            deferredObject.Uri = this.GetArrayString(firstChild, "uri");
                            deferredObject.Deferred = true;

                            payloadObject.PayloadObjects.Add(deferredObject);
                        }
                        else if (firstChild != null && firstChild.Name == "__mediaresource")
                        {
                            PayloadNamedStream stream = new PayloadNamedStream();
                            stream.Name = field.Name;
                            stream.ContentType = this.GetArrayString(firstChild, "content-type");
                            stream.EditLink = this.GetArrayString(firstChild, "edit_media");
                            stream.SelfLink = this.GetArrayString(firstChild, "media_src");
                            stream.ETag = this.GetArrayString(firstChild, "etag");
                            payloadObject.NamedStreams.Add(stream);
                        }
                        else
                        {
                            JSObject objectValue = (JSObject)field.GetValue(field);
                            var objectValueFields = objectValue.GetFields(BindingFlags.Default);
                            if (objectValueFields.Any(f => f.Name == "__metadata" && GetArrayString((JSField)f, "uri") != null))
                            {
                                PayloadObject referencePayloadObject = parseJsonObject(objectValue);
                                referencePayloadObject.Name = field.Name;
                                referencePayloadObject.Reference = true;

                                payloadObject.PayloadObjects.Add(referencePayloadObject);
                            }
                            else
                            {
                                PayloadComplexProperty payloadProperty = this.parseComplexObject(payloadObject, field);    // Complex object
                                payloadObject.PayloadProperties.Add(payloadProperty);
                            }
                        }
                    }
                }
                else
                {
                    PayloadProperty payloadProperty = this.parseSimpleObject(payloadObject, field);
                    payloadObject.PayloadProperties.Add(payloadProperty);
                }
            }

            return payloadObject;
        }
Example #24
0
        private void VerifyInsertResponse(ResourceType type, PayloadObject inserted, PayloadObject returned)
        {
            // need to 'follow' deferred links to ensure that they're correct
            // doesn't need to match exactly
            AstoriaTestLog.AreEqual(inserted.Type, returned.Type, "Types do not match");

            VerifyProperties(type, inserted, returned, true, (rp => !rp.Facets.ServerGenerated));
        }
Example #25
0
 public static string ConstructETag(ResourceContainer container, PayloadObject entity)
 {
     KeyExpression key = ConstructKey(container, entity);
     return key.ETag;
 }
Example #26
0
 public PayloadSimpleProperty(PayloadObject parent)
     : base(parent)
 {
 }
Example #27
0
        // DO NOT INSTANTIATE THIS DIRECTLY. Use either CommonPayload.CreateCommonPayload or AstoriaResponse.CommonPayload
        internal JSONPayload(AstoriaRequestResponseBase rr)
            : base(rr)
        {
            string jsonString = this.RawPayload;

            if (jsonString == null)
            {
                this.Value = null;
                return;
            }

            jsonString = StripSecurityWrapper(jsonString);

            object jsonData = null;

            try
            {
                jsonData = Evaluator.EvalToObject("(" + jsonString + ")");
            }
            catch (Exception e)
            {
                this.Value = jsonString;
                return;
            }

            if (jsonData is ArrayObject)
            {
                this.Resources = ParseJsonArray((ArrayObject)jsonData);
            }
            else if (jsonData is JSObject)
            {
                FieldInfo[] fields = ((JSObject)jsonData).GetFields(BindingFlags.Default);

                // v2-style array, with count/page
                if (fields.Any(field => field.Name == v2JsonResultsField))
                {
                    foreach (FieldInfo field in fields)
                    {
                        object value = field.GetValue(field);
                        switch (field.Name)
                        {
                        case v2NextField:
                            this.NextLink = value.ToString();
                            break;

                        case v2CountField:
                            this.Count = Convert.ToInt64(value.ToString());
                            break;

                        case v2JsonResultsField:
                            if (value is ArrayObject)
                            {
                                this.Resources = ParseJsonArray((ArrayObject)value);
                            }
                            else
                            {
                                AstoriaTestLog.FailAndThrow("Array expected in results field");
                            }
                            break;

                        default:
                            AstoriaTestLog.FailAndThrow("Field '" + field.Name + "' unexpected");
                            break;
                        }
                    }
                }
                else if (fields.Any(field => field.Name == "__metadata"))
                {
                    this.Resources = ParseSingleJsonObject((JSObject)jsonData);   // entry
                }
                else
                {
                    if (fields.Length > 1)
                    {
                        AstoriaTestLog.FailAndThrow("Single field expected for non-entry payload");
                    }

                    FieldInfo field = fields[0];
                    object    value = field.GetValue(field);

                    PayloadObject   payloadObject = new PayloadObject(this);
                    PayloadProperty property;
                    if (value is JSObject)
                    {
                        property = parseComplexObject(payloadObject, (JSField)field);
                    }
                    else
                    {
                        property = parseSimpleObject(payloadObject, (JSField)field);
                    }

                    if (property.Name != "uri")
                    {
                        this.Resources = property;
                    }
                    else
                    {
                        // this is to match the resulting structure for parsing links in ATOM / json collections
                        PayloadObject temp = new PayloadObject(this);
                        temp.Name = property.Name;
                        temp.PayloadProperties.Add(property);
                        this.Resources = new List <PayloadObject>()
                        {
                            temp
                        };
                    }
                }
            }
            else
            {
                this.Value = jsonString; // must be $value
            }
        }
Example #28
0
 public PayloadSimpleProperty(PayloadObject parent)
     : base(parent)
 { }
Example #29
0
        internal PayloadObject ParseEntry(XElement xmlData)
        {
            PayloadObject payloadObject = new PayloadObject(this);

            #region edit link
            XElement linkEdit = xmlData.Elements(atom + "link").SingleOrDefault(l => l.Attribute("rel") != null && l.Attribute("rel").Value == "edit");
            if (linkEdit != null)
            {
                payloadObject.Uri = linkEdit.Attribute("href").Value;
            }
            #endregion

            #region id link
            XElement idNode = xmlData.Element(atom + "id");
            if (idNode != null)
            {
                payloadObject.Uri = idNode.Value;
            }
            // TODO: compare the edit link to the ID node's value
            #endregion

            #region name
            XElement titleNode = xmlData.Parent;
            if (titleNode != null && titleNode.Name == m + "inline")
            {
                XAttribute titleAttribute = titleNode.Parent.Attribute("title");
                if (titleAttribute != null)
                {
                    payloadObject.Name = titleAttribute.Value;
                }
            }
            else if (titleNode != null)
            {
                titleNode = titleNode.Element(atom + "title");
                if (titleNode != null)
                {
                    payloadObject.Name = titleNode.Value;
                }
            }
            else if (linkEdit != null)
            {
                XAttribute titleAttribute = linkEdit.Attribute("title");
                if (titleAttribute != null)
                {
                    payloadObject.Name = titleAttribute.Value;
                }
            }
            #endregion

            #region type
            bool         isMediaLink = false;
            XElement     category    = xmlData.Element(atom + "category");
            ResourceType type        = null;
            if (category != null)
            {
                XAttribute term = category.Attribute("term");
                if (term != null)
                {
                    payloadObject.Type = term.Value;
                    type = Workspace.ServiceContainer.ResourceTypes.Single(rt => rt.Namespace + "." + rt.Name == term.Value);
                    if (type.Facets.HasStream)
                    {
                        isMediaLink = true;
                    }
                }
            }
            #endregion

            #region friendly feeds
            ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Title, xmlData, payloadObject);
            ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Summary, xmlData, payloadObject);
            ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Rights, xmlData, payloadObject);

            //This is the correct mapping for Friendly Feeds SyndicationItemProperty.Published
            XElement ffEntryPublishedNode = xmlData.Element(atom + "published");
            if (ffEntryPublishedNode != null)
            {
                payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.Published] = ffEntryPublishedNode.Value;
            }

            //This is the correct mapping for Friendly Feeds SyndicationItemProperty.Updated
            XElement ffEntryUpdatedNode = xmlData.Element(atom + "updated");
            if (ffEntryUpdatedNode != null)
            {
                payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.Updated] = ffEntryUpdatedNode.Value;
            }

            //This is the correct mapping for Friendly Feeds Author Node
            XElement ffEntryAuthorNode = xmlData.Element(atom + "author");
            if (ffEntryAuthorNode != null)
            {
                //Friendly Feeds SyndicationItemProperty.AuthorEmail
                XElement ffEmailNode = ffEntryAuthorNode.Element(atom + "email");
                if (ffEmailNode != null)
                {
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorEmail] = ffEmailNode.Value;
                }

                //Friendly Feeds SyndicationItemProperty.AuthorName
                XElement ffNameNode = ffEntryAuthorNode.Element(atom + "name");
                if (ffNameNode != null)
                {
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorName] = ffNameNode.Value;
                }

                //Friendly Feeds SyndicationItemProperty.AuthorUri
                XElement ffUriNode = ffEntryAuthorNode.Element(atom + "uri");
                if (ffUriNode != null)
                {
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorUri] = ffUriNode.Value;
                }
            }

            //This is the correct mapping for Friendly Feeds Contributor Node
            XElement ffEntryContributorNode = xmlData.Element(atom + "contributor");
            if (ffEntryContributorNode != null)
            {
                //Friendly Feeds SyndicationItemProperty.ContributorEmail
                XElement ffEmailNode = ffEntryContributorNode.Element(atom + "email");
                if (ffEmailNode != null)
                {
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorEmail] = ffEmailNode.Value;
                }

                //Friendly Feeds SyndicationItemProperty.ContributorName
                XElement ffNameNode = ffEntryContributorNode.Element(atom + "name");
                if (ffNameNode != null)
                {
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorName] = ffNameNode.Value;
                }

                //Friendly Feeds SyndicationItemProperty.ContributorUri
                XElement ffUriNode = ffEntryContributorNode.Element(atom + "uri");
                if (ffUriNode != null)
                {
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorUri] = ffUriNode.Value;
                }
            }

            #endregion

            #region etag
            if (xmlData.HasAttributes)
            {
                XAttribute etagNodeAttribute = xmlData.Attribute(m + "etag");
                if (etagNodeAttribute != null)
                {
                    payloadObject.ETag = etagNodeAttribute.Value;
                }
            }
            #endregion

            #region properties
            XElement content    = xmlData.Element(atom + "content");
            XElement properties = null;
            if (content != null)
            {
                XAttribute contentType = content.Attribute("type");
                if (contentType != null)
                {
                    if (!isMediaLink)
                    {
                        StringComparison comp;
                        if (WasResponse)
                        {
                            comp = StringComparison.InvariantCulture;
                        }
                        else
                        {
                            comp = StringComparison.InvariantCultureIgnoreCase;
                        }
                        if (!contentType.Value.Equals("application/xml", comp))
                        {
                            AstoriaTestLog.AreEqual("application/xml", contentType.Value, "Unexpected type on content element", true);
                        }
                        properties = content.Element(m + "properties");
                    }
                    // TODO: save content type if its a media link
                }
            }

            if (isMediaLink)
            {
                properties = xmlData.Element(m + "properties");
            }

            if (properties != null)
            {
                foreach (XElement element in properties.Elements())
                {
                    PayloadProperty property;
                    if (element.HasElements)
                    {
                        property = ParseComplexProperty(payloadObject, element);
                    }
                    else
                    {
                        property = ParseSimpleProperty(payloadObject, element);
                    }
                    payloadObject.PayloadProperties.Add(property);
                }
            }
            #endregion

            #region links
            foreach (XElement link in xmlData.Elements(atom + "link"))
            {
                Uri linkRel = new Uri(link.Attribute("rel").Value, UriKind.RelativeOrAbsolute);
                if (linkRel.IsAbsoluteUri)
                {
                    string linkRelValue = linkRel.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
                    if (linkRelValue.StartsWith(DataWebRelatedNamespace, StringComparison.Ordinal))
                    {
                        XElement inlineTag = link.Element(m + "inline");
                        if (inlineTag != null)
                        {
                            PayloadObject nestedPayloadObject = new PayloadObject(this);
                            nestedPayloadObject.Name = linkRelValue.Substring(DataWebRelatedNamespace.Length);

                            string linkType = link.Attribute("type").Value;
                            if (linkType.Contains("feed"))
                            {
                                if (inlineTag.HasElements)
                                {
                                    nestedPayloadObject.PayloadObjects.AddRange(this.ParseFeed(inlineTag.Elements().Single()));
                                }
                            }
                            else if (linkType.Contains("entry"))
                            {
                                if (inlineTag.HasElements)
                                {
                                    nestedPayloadObject = this.ParseEntry(inlineTag.Elements().Single());
                                }

                                nestedPayloadObject.Reference = true;
                            }

                            payloadObject.PayloadObjects.Add(nestedPayloadObject);
                        }
                        else
                        {
                            // deferred links
                            PayloadObject deferredObject = new PayloadObject(this);
                            deferredObject.Name = linkRelValue.Substring(DataWebRelatedNamespace.Length);
                            if (link.Attribute("href") != null)
                            {
                                deferredObject.Uri = link.Attribute("href").Value;
                            }
                            deferredObject.Deferred = true;

                            payloadObject.PayloadObjects.Add(deferredObject);
                        }
                    }
                    else if (linkRelValue.StartsWith(DataWebMediaResourceNamespace))
                    {
                        string             name        = linkRelValue.Substring(DataWebMediaResourceNamespace.Length);
                        PayloadNamedStream namedStream = payloadObject.NamedStreams.SingleOrDefault(s => s.Name == name);
                        if (namedStream == null)
                        {
                            namedStream = new PayloadNamedStream()
                            {
                                Name = name
                            };
                            payloadObject.NamedStreams.Add(namedStream);
                        }

                        UpdateNamedStreamMetadata(link, namedStream);
                        namedStream.SelfLink = link.Attribute("href").Value;
                    }
                    else if (linkRelValue.StartsWith(DataWebMediaResourceEditNamespace))
                    {
                        string             name        = linkRelValue.Substring(DataWebMediaResourceEditNamespace.Length);
                        PayloadNamedStream namedStream = payloadObject.NamedStreams.SingleOrDefault(s => s.Name == name);
                        if (namedStream == null)
                        {
                            namedStream = new PayloadNamedStream()
                            {
                                Name = name
                            };
                            payloadObject.NamedStreams.Add(namedStream);
                        }

                        UpdateNamedStreamMetadata(link, namedStream);
                        namedStream.EditLink = link.Attribute("href").Value;
                    }
                }
            }
            #endregion

            return(payloadObject);
        }
Example #30
0
        private void ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty itemProperty, XElement xmlData, PayloadObject payloadObject)
        {
            XElement element = xmlData.Element(atom + itemProperty.ToString().ToLowerInvariant());
            if (element != null)
            {
                var value = element.Value;

                XAttribute nullAttribute = element.Attribute(m + "null");
                if (nullAttribute != null && nullAttribute.Value == "true")
                {
                    value = null;
                }

                payloadObject.SyndicationItemProperties[itemProperty] = value;
            }
        }
Example #31
0
        public static string ConstructETag(ResourceContainer container, PayloadObject entity)
        {
            KeyExpression key = ConstructKey(container, entity);

            return(key.ETag);
        }
Example #32
0
        internal PayloadSimpleProperty ParseSimpleProperty(PayloadObject parent, XElement xmlData)
        {
            PayloadSimpleProperty payloadProperty = new PayloadSimpleProperty(parent);
            payloadProperty.Name = xmlData.Name.LocalName;
            payloadProperty.Value = xmlData.Value;

            XAttribute nullAttribute = xmlData.Attribute(m + "null");
            if (nullAttribute != null && nullAttribute.Value == "true")
            {
                payloadProperty.Value = null;
                payloadProperty.IsNull = true;
            }

            XAttribute typeAttribute = xmlData.Attribute(m + "type");
            if (typeAttribute != null)
                payloadProperty.Type = typeAttribute.Value;

            return payloadProperty;
        }
Example #33
0
        internal PayloadSimpleProperty parseSimpleObject(PayloadObject parent, JSField field)
        {
            PayloadSimpleProperty payloadProperty = new PayloadSimpleProperty(parent);
            payloadProperty.Name = field.Name;

            object val = field.GetValue(field);

            if (val is System.DBNull)
            {
                payloadProperty.Value = null;
                payloadProperty.Type = null;
                payloadProperty.IsNull = true;
            }
            else
            {
                payloadProperty.Type = AstoriaUnitTests.Data.TypeData.FindForType(val.GetType()).GetEdmTypeName();
                payloadProperty.Value = ConvertJsonValue(val);
                payloadProperty.IsNull = false;
            }

            return payloadProperty;
        }
Example #34
0
        internal PayloadComplexProperty ParseComplexProperty(PayloadObject parent, XElement xmlData)
        {
            PayloadComplexProperty payloadProperty = new PayloadComplexProperty(parent);
            payloadProperty.Name = xmlData.Name.LocalName;

            XAttribute nullAttribute = xmlData.Attribute(m + "null");
            if (nullAttribute != null && nullAttribute.Value == "true")
                payloadProperty.IsNull = true;

            XAttribute typeAttribute = xmlData.Attribute(m + "type");
            if (typeAttribute != null)
                payloadProperty.Type = typeAttribute.Value;

            foreach (XElement property in xmlData.Elements())
            {
                PayloadProperty subProperty;
                if (property.HasElements)
                {
                    subProperty = ParseComplexProperty(parent, property);
                }
                else
                {
                    subProperty = ParseSimpleProperty(parent, property);
                }
                payloadProperty.PayloadProperties.Add(subProperty.Name, subProperty);
            }

            return payloadProperty;
        }
Example #35
0
        // DO NOT INSTANTIATE THIS DIRECTLY. Use either CommonPayload.CreateCommonPayload or AstoriaResponse.CommonPayload
        internal JSONPayload(AstoriaRequestResponseBase rr)
            : base(rr)
        {
            string jsonString = this.RawPayload;
            if (jsonString == null)
            {
                this.Value = null;
                return;
            }

            jsonString = StripSecurityWrapper(jsonString);

            object jsonData = null;
            try
            {
                jsonData = Evaluator.EvalToObject("(" + jsonString + ")");
            }
            catch (Exception e)
            {
                this.Value = jsonString;
                return;
            }

            if (jsonData is ArrayObject)
            {
                this.Resources = ParseJsonArray((ArrayObject)jsonData);
            }
            else if (jsonData is JSObject)
            {
                FieldInfo[] fields = ((JSObject)jsonData).GetFields(BindingFlags.Default);

                // v2-style array, with count/page
                if (fields.Any(field => field.Name == v2JsonResultsField))
                {
                    foreach (FieldInfo field in fields)
                    {
                        object value = field.GetValue(field);
                        switch (field.Name)
                        {
                            case v2NextField:
                                this.NextLink = value.ToString();
                                break;

                            case v2CountField:
                                this.Count = Convert.ToInt64(value.ToString());
                                break;

                            case v2JsonResultsField:
                                if (value is ArrayObject)
                                    this.Resources = ParseJsonArray((ArrayObject)value);
                                else
                                    AstoriaTestLog.FailAndThrow("Array expected in results field");
                                break;

                            default:
                                AstoriaTestLog.FailAndThrow("Field '" + field.Name + "' unexpected");
                                break;
                        }
                    }
                }
                else if (fields.Any(field => field.Name == "__metadata"))
                {
                    this.Resources = ParseSingleJsonObject((JSObject)jsonData);   // entry
                }
                else
                {
                    if (fields.Length > 1)
                        AstoriaTestLog.FailAndThrow("Single field expected for non-entry payload");

                    FieldInfo field = fields[0];
                    object value = field.GetValue(field);

                    PayloadObject payloadObject = new PayloadObject(this);
                    PayloadProperty property;
                    if (value is JSObject)
                        property = parseComplexObject(payloadObject, (JSField)field);
                    else
                        property = parseSimpleObject(payloadObject, (JSField)field);

                    if (property.Name != "uri")
                        this.Resources = property;
                    else
                    {
                        // this is to match the resulting structure for parsing links in ATOM / json collections
                        PayloadObject temp = new PayloadObject(this);
                        temp.Name = property.Name;
                        temp.PayloadProperties.Add(property);
                        this.Resources = new List<PayloadObject>() { temp };
                    }
                }
            }
            else
            {
                this.Value = jsonString; // must be $value
            }
        }
Example #36
0
 public PayloadProperty(PayloadObject parent)
 {
     this.ParentObject = parent;
     this.MappedOutOfContent = false; //by default, assume not
 }
Example #37
0
        private void VerifyProperties(ResourceType type, PayloadObject inserted, PayloadObject returned, bool missingInsertPropertiesOk, Func <ResourceProperty, bool> strictEquality)
        {
            List <string> propertyNames = inserted.PayloadProperties.Union(returned.PayloadProperties).Select(p => p.Name).ToList();

            propertyNames.AddRange(inserted.CustomEpmMappedProperties.Keys);
            propertyNames.AddRange(returned.CustomEpmMappedProperties.Keys);

            foreach (string propertyName in propertyNames.Distinct())
            {
                PayloadProperty insertedProperty;
                if (inserted.Format == SerializationFormatKind.JSON) //in JSON the first one wins
                {
                    insertedProperty = inserted.PayloadProperties.FirstOrDefault(p => p.Name == propertyName);
                }
                else //in xml the last one wins
                {
                    insertedProperty = inserted.PayloadProperties.LastOrDefault(p => p.Name == propertyName);
                }
                bool insertHadProperty = insertedProperty != null;

                PayloadProperty returnedProperty    = returned.PayloadProperties.LastOrDefault(p => p.Name == propertyName);;
                bool            returnedHadProperty = returnedProperty != null;

                ResourceProperty property = type.Properties.OfType <ResourceProperty>().SingleOrDefault(p => p.Name == propertyName);

                if (property == null || !property.Facets.IsDeclaredProperty)
                {
                    if (!type.Facets.IsOpenType)
                    {
                        string error = "included dynamic property '" + propertyName + "' despite '" + type.Name + "' not being an open type";
                        if (insertHadProperty && returnedHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Both the inserted and returned objects " + error);
                        }
                        else if (insertHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("The inserted object " + error);
                        }
                        else if (returnedHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("The returned object " + error);
                        }
                    }
                    else
                    {
                        if (insertHadProperty && returnedHadProperty)
                        {
                            CompareDynamicPropertyValues(insertedProperty, returnedProperty);
                        }
                        else if (insertHadProperty)
                        {
                            // only acceptable if inserted value was null
                            if (insertedProperty.IsNull)
                            {
                                AstoriaTestLog.FailAndThrow("Returned object missing non-null dynamic property '" + propertyName + "'");
                            }
                        }
                    }
                }
                else
                {
                    if (property.IsNavigation)
                    {
                        // the insert payload may not specify this property
                        //PayloadObject insertedObject = inserted.PayloadObjects.SingleOrDefault(o => o.Name == property.Name);
                        PayloadObject returnedObject = returned.PayloadObjects.Single(o => o.Name == property.Name);

                        // returned thing should be deferred whether its a reference or not
                        AstoriaTestLog.AreEqual(true, returnedObject.Deferred, "!returnedObject.Deferred", false);

                        // TODO: verify only expected links are present (based on uri and payload values as well)
                    }
                    else
                    {
                        if (insertHadProperty && returnedHadProperty)
                        {
                            try
                            {
                                ComparePropertyValues(property, insertedProperty, returnedProperty, strictEquality(property));
                            }
                            catch (Exception e)
                            {
                                throw new TestFailedException("Value of property '" + property.Name + "' does not match inserted value", null, null, e);
                            }
                        }
                        else if (insertHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Returned object unexpectedly missing declared property '" + propertyName + "'");
                        }
                        else if (returnedHadProperty)
                        {
                            if (missingInsertPropertiesOk)
                            {
                                AstoriaTestLog.WriteLineIgnore("Ignoring missing declared property '" + propertyName + "' in insert payload");
                            }
                            else
                            {
                                AstoriaTestLog.FailAndThrow("Inserted object unexpectedly missing declared property '" + propertyName + "'");
                            }
                        }
                    }
                }
            }
        }
        internal static KeyedResourceInstance CreateKeyedResourceInstanceFromPayloadObject(ResourceContainer container, ResourceType resourceType, PayloadObject payloadObject)
        {
            List<ResourceInstanceProperty> properties = new List<ResourceInstanceProperty>();
            List<ResourceInstanceProperty> keyProperties = new List<ResourceInstanceProperty>();

            foreach (ResourceProperty property in resourceType.Properties.OfType<ResourceProperty>())
            {
                if (property.IsNavigation)
                    continue;

                if (property.IsComplexType)
                {
                    PayloadComplexProperty fromPayload = payloadObject[property.Name] as PayloadComplexProperty;
                    properties.Add(ConvertComplexPayloadObjectToComplexProperty(property, fromPayload));
                }
                else
                {
                    string stringValue;
                    if (payloadObject.PayloadProperties.Any(p => p.Name == property.Name))
                    {
                        PayloadSimpleProperty fromPayload = payloadObject[property.Name] as PayloadSimpleProperty;
                        stringValue = fromPayload.Value;
                    }
                    else
                    {
                        if (!payloadObject.CustomEpmMappedProperties.TryGetValue(property.Name, out stringValue))
                            stringValue = null;
                    }

                    ResourceInstanceProperty newProperty = null;
                    object val = CommonPayload.DeserializeStringToObject(stringValue, property.Type.ClrType, false, payloadObject.Format);
                    newProperty = new ResourceInstanceSimpleProperty(property.Name, new NodeValue(val, property.Type));

                    if (property.PrimaryKey != null)
                        keyProperties.Add(newProperty);
                    else
                        properties.Add(newProperty);
                }
            }

            ResourceInstanceKey key = new ResourceInstanceKey(container, resourceType, keyProperties.ToArray());
            return new KeyedResourceInstance(key, properties.ToArray());

        }
Example #39
0
 public PayloadProperty(PayloadObject parent)
 {
     this.ParentObject       = parent;
     this.MappedOutOfContent = false; //by default, assume not
 }
Example #40
0
 public PayloadComplexProperty(PayloadObject parent)
     : base(parent)
 {
     PayloadProperties = new Dictionary<string, PayloadProperty>();
 }
Example #41
0
 public PayloadComplexProperty(PayloadObject parent)
     : base(parent)
 {
     PayloadProperties = new Dictionary <string, PayloadProperty>();
 }
Example #42
0
 internal PayloadObject ParseUriNode(XElement node)
 {
     PayloadObject po = new PayloadObject(this);
     PayloadSimpleProperty property = new PayloadSimpleProperty(po);
     property.Value = node.Value;
     property.Name = node.Name.LocalName;
     po.Name = node.Name.LocalName;
     po.PayloadProperties.Add(property);
     return po;
 }
Example #43
0
        internal PayloadObject ParseEntry(XElement xmlData)
        {
            PayloadObject payloadObject = new PayloadObject(this);

            #region edit link
            XElement linkEdit = xmlData.Elements(atom + "link").SingleOrDefault(l => l.Attribute("rel") != null && l.Attribute("rel").Value == "edit");
            if (linkEdit != null)
                payloadObject.Uri = linkEdit.Attribute("href").Value;
            #endregion

            #region id link
            XElement idNode = xmlData.Element(atom + "id");
            if (idNode != null)
                payloadObject.Uri = idNode.Value;
            // TODO: compare the edit link to the ID node's value
            #endregion

            #region name
            XElement titleNode = xmlData.Parent;
            if (titleNode != null && titleNode.Name == m + "inline")
            {
                XAttribute titleAttribute = titleNode.Parent.Attribute("title");
                if (titleAttribute != null)
                    payloadObject.Name = titleAttribute.Value;
            }
            else if (titleNode != null)
            {
                titleNode = titleNode.Element(atom + "title");
                if (titleNode != null)
                    payloadObject.Name = titleNode.Value;
            }
            else if (linkEdit != null)
            {
                XAttribute titleAttribute = linkEdit.Attribute("title");
                if (titleAttribute != null)
                    payloadObject.Name = titleAttribute.Value;
            }
            #endregion

            #region type
            bool isMediaLink = false;
            XElement category = xmlData.Element(atom + "category");
            ResourceType type = null;
            if (category != null)
            {
                XAttribute term = category.Attribute("term");
                if (term != null)
                {
                    payloadObject.Type = term.Value;
                    type = Workspace.ServiceContainer.ResourceTypes.Single(rt => rt.Namespace + "." + rt.Name == term.Value);
                    if (type.Facets.HasStream)
                        isMediaLink = true;
                }
            }
            #endregion

            #region friendly feeds
            ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Title, xmlData, payloadObject);
            ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Summary, xmlData, payloadObject);
            ParseNullableSyndicationItemProperty(AtomSyndicationItemProperty.Rights, xmlData, payloadObject);

            //This is the correct mapping for Friendly Feeds SyndicationItemProperty.Published
            XElement ffEntryPublishedNode = xmlData.Element(atom + "published");
            if (ffEntryPublishedNode != null)
                payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.Published] = ffEntryPublishedNode.Value;

            //This is the correct mapping for Friendly Feeds SyndicationItemProperty.Updated
            XElement ffEntryUpdatedNode = xmlData.Element(atom + "updated");
            if (ffEntryUpdatedNode != null)
                payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.Updated] = ffEntryUpdatedNode.Value;

            //This is the correct mapping for Friendly Feeds Author Node
            XElement ffEntryAuthorNode = xmlData.Element(atom + "author");
            if (ffEntryAuthorNode != null)
            {
                //Friendly Feeds SyndicationItemProperty.AuthorEmail
                XElement ffEmailNode = ffEntryAuthorNode.Element(atom + "email");
                if (ffEmailNode != null)
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorEmail] = ffEmailNode.Value;

                //Friendly Feeds SyndicationItemProperty.AuthorName
                XElement ffNameNode = ffEntryAuthorNode.Element(atom + "name");
                if (ffNameNode != null)
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorName] = ffNameNode.Value;

                //Friendly Feeds SyndicationItemProperty.AuthorUri
                XElement ffUriNode = ffEntryAuthorNode.Element(atom + "uri");
                if (ffUriNode != null)
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.AuthorUri] = ffUriNode.Value;
            }

            //This is the correct mapping for Friendly Feeds Contributor Node
            XElement ffEntryContributorNode = xmlData.Element(atom + "contributor");
            if (ffEntryContributorNode != null)
            {
                //Friendly Feeds SyndicationItemProperty.ContributorEmail
                XElement ffEmailNode = ffEntryContributorNode.Element(atom + "email");
                if (ffEmailNode != null)
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorEmail] = ffEmailNode.Value;

                //Friendly Feeds SyndicationItemProperty.ContributorName
                XElement ffNameNode = ffEntryContributorNode.Element(atom + "name");
                if (ffNameNode != null)
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorName] = ffNameNode.Value;

                //Friendly Feeds SyndicationItemProperty.ContributorUri
                XElement ffUriNode = ffEntryContributorNode.Element(atom + "uri");
                if (ffUriNode != null)
                    payloadObject.SyndicationItemProperties[AtomSyndicationItemProperty.ContributorUri] = ffUriNode.Value;
            }

            #endregion

            #region etag
            if (xmlData.HasAttributes)
            {
                XAttribute etagNodeAttribute = xmlData.Attribute(m + "etag");
                if (etagNodeAttribute != null)
                    payloadObject.ETag = etagNodeAttribute.Value;
            }
            #endregion

            #region properties
            XElement content = xmlData.Element(atom + "content");
            XElement properties = null;
            if (content != null)
            {
                XAttribute contentType = content.Attribute("type");
                if (contentType != null)
                {
                    if (!isMediaLink)
                    {
                        StringComparison comp;
                        if (WasResponse)
                            comp = StringComparison.InvariantCulture;
                        else
                            comp = StringComparison.InvariantCultureIgnoreCase;
                        if (!contentType.Value.Equals("application/xml", comp))
                            AstoriaTestLog.AreEqual("application/xml", contentType.Value, "Unexpected type on content element", true);
                        properties = content.Element(m + "properties");
                    }
                    // TODO: save content type if its a media link
                }
            }

            if (isMediaLink)
                properties = xmlData.Element(m + "properties");

            if (properties != null)
            {
                foreach (XElement element in properties.Elements())
                {
                    PayloadProperty property;
                    if (element.HasElements)
                    {
                        property = ParseComplexProperty(payloadObject, element);
                    }
                    else
                    {
                        property = ParseSimpleProperty(payloadObject, element);
                    }
                    payloadObject.PayloadProperties.Add(property);
                }
            }
            #endregion

            #region links
            foreach (XElement link in xmlData.Elements(atom + "link"))
            {
                Uri linkRel = new Uri(link.Attribute("rel").Value, UriKind.RelativeOrAbsolute);
                if (linkRel.IsAbsoluteUri)
                {
                    string linkRelValue = linkRel.GetComponents(UriComponents.AbsoluteUri, UriFormat.SafeUnescaped);
                    if (linkRelValue.StartsWith(DataWebRelatedNamespace, StringComparison.Ordinal))
                    {
                        XElement inlineTag = link.Element(m + "inline");
                        if (inlineTag != null)
                        {
                            PayloadObject nestedPayloadObject = new PayloadObject(this);
                            nestedPayloadObject.Name = linkRelValue.Substring(DataWebRelatedNamespace.Length);

                            string linkType = link.Attribute("type").Value;
                            if (linkType.Contains("feed"))
                            {
                                if (inlineTag.HasElements)
                                    nestedPayloadObject.PayloadObjects.AddRange(this.ParseFeed(inlineTag.Elements().Single()));
                            }
                            else if (linkType.Contains("entry"))
                            {
                                if (inlineTag.HasElements)
                                    nestedPayloadObject = this.ParseEntry(inlineTag.Elements().Single());

                                nestedPayloadObject.Reference = true;
                            }

                            payloadObject.PayloadObjects.Add(nestedPayloadObject);
                        }
                        else
                        {
                            // deferred links
                            PayloadObject deferredObject = new PayloadObject(this);
                            deferredObject.Name = linkRelValue.Substring(DataWebRelatedNamespace.Length);
                            if (link.Attribute("href") != null)
                                deferredObject.Uri = link.Attribute("href").Value;
                            deferredObject.Deferred = true;

                            payloadObject.PayloadObjects.Add(deferredObject);
                        }
                    }
                    else if (linkRelValue.StartsWith(DataWebMediaResourceNamespace))
                    {
                        string name = linkRelValue.Substring(DataWebMediaResourceNamespace.Length);
                        PayloadNamedStream namedStream = payloadObject.NamedStreams.SingleOrDefault(s => s.Name == name);
                        if (namedStream == null)
                        {
                            namedStream = new PayloadNamedStream() { Name = name };
                            payloadObject.NamedStreams.Add(namedStream);
                        }

                        UpdateNamedStreamMetadata(link, namedStream);
                        namedStream.SelfLink = link.Attribute("href").Value;
                    }
                    else if (linkRelValue.StartsWith(DataWebMediaResourceEditNamespace))
                    {
                        string name = linkRelValue.Substring(DataWebMediaResourceEditNamespace.Length);
                        PayloadNamedStream namedStream = payloadObject.NamedStreams.SingleOrDefault(s => s.Name == name);
                        if (namedStream == null)
                        {
                            namedStream = new PayloadNamedStream() { Name = name };
                            payloadObject.NamedStreams.Add(namedStream);
                        }

                        UpdateNamedStreamMetadata(link, namedStream);
                        namedStream.EditLink = link.Attribute("href").Value;
                    }
                }
            }
            #endregion

            return payloadObject;
        }
Example #44
0
        private void Verify(AstoriaRequest request)
        {
            RequestVerb verb  = request.EffectiveVerb;
            bool        merge = verb == RequestVerb.Patch;

            PayloadObject entityBefore;

            if (!TryGetSingleObjectFromPayload(request.BeforeUpdatePayload, out entityBefore))
            {
                AstoriaTestLog.FailAndThrow("Pre-update payload did not contain a single entity");
            }

            // determine the type based on what was there (doing .Single() doesn't work for MEST, because the type shows up twice)
            ResourceType type = request.Workspace.ServiceContainer.ResourceTypes.First(rt => entityBefore.Type.Equals(rt.Namespace + "." + rt.Name));

            PayloadObject entityAfter;

            if (!TryGetSingleObjectFromPayload(request.AfterUpdatePayload, out entityAfter))
            {
                AstoriaTestLog.FailAndThrow("Post-update payload did not contain a single entity");
            }

            CommonPayload updatePayload = request.CommonPayload;
            PayloadObject entityUpdate  = null;

            if (request.URI.EndsWith("$value"))
            {
                Match match = Regex.Match(request.URI, @".*/(.+)/\$value");
                if (!match.Success)
                {
                    AstoriaTestLog.FailAndThrow("Could not determine property name for $value request");
                }

                string propertyValue = null;
                if (request.ContentType.Equals(SerializationFormatKinds.MimeApplicationOctetStream, StringComparison.InvariantCultureIgnoreCase))
                {
                    object value = (request.UpdateTree as ResourceInstanceSimpleProperty).PropertyValue;
                    if (updatePayload.Format == SerializationFormatKind.JSON)
                    {
                        propertyValue = JSONPayload.ConvertJsonValue(value);
                    }
                    else
                    {
                        AstoriaTestLog.FailAndThrow("Unsure how to fake property value");
                    }
                }
                else
                {
                    propertyValue = request.Payload;
                }

                entityUpdate = new PayloadObject(updatePayload);
                PayloadSimpleProperty propertyUpdate = new PayloadSimpleProperty(entityUpdate);
                propertyUpdate.Name  = match.Groups[1].Value;
                propertyUpdate.Value = propertyValue;
                entityUpdate.PayloadProperties.Add(propertyUpdate);
                merge = true; //PUT to a single property doesn't reset the resource
            }
            else if (!TryGetSingleObjectFromPayload(updatePayload, out entityUpdate))
            {
                // must be a single property update
                PayloadProperty propertyUpdate = updatePayload.Resources as PayloadProperty;
                if (propertyUpdate == null)
                {
                    AstoriaTestLog.FailAndThrow("Expected either a property or an entity in the update payload");
                }
                entityUpdate = new PayloadObject(updatePayload);
                entityUpdate.PayloadProperties.Add(propertyUpdate);
                propertyUpdate.ParentObject = entityUpdate;
                merge = true; //PUT to a single property doesn't reset the resource
            }

            List <string> allPropertyNames = entityBefore.PayloadProperties
                                             .Union(entityAfter.PayloadProperties)
                                             .Union(entityUpdate.PayloadProperties)
                                             .Select(p => p.Name)
                                             .ToList();

            allPropertyNames.AddRange(entityBefore.CustomEpmMappedProperties.Keys);
            allPropertyNames.AddRange(entityUpdate.CustomEpmMappedProperties.Keys);
            allPropertyNames.AddRange(entityAfter.CustomEpmMappedProperties.Keys);

            foreach (string propertyName in allPropertyNames.Distinct())
            {
                PayloadProperty original            = null;
                bool            originalHadProperty = entityBefore.PayloadProperties.Any(p => (original = p).Name == propertyName);

                PayloadProperty update            = null;
                bool            updateHadProperty = entityUpdate.PayloadProperties.Any(p => (update = p).Name == propertyName);

                PayloadProperty final            = null;
                bool            finalHadProperty = entityAfter.PayloadProperties.Any(p => (final = p).Name == propertyName);

                if (type.Properties.Any(p => p.Name == propertyName && p.Facets.IsDeclaredProperty))
                {
                    // declared property

                    if (!finalHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Final version of entity is missing declared property '" + propertyName + "'");
                    }

                    ResourceProperty property = type.Properties[propertyName] as ResourceProperty;

                    if (property.IsNavigation)
                    {
                        continue;
                    }

                    if (!originalHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Original version of entity is missing declared property '" + propertyName + "'");
                    }

                    bool checkValue = property.PrimaryKey == null && !property.Facets.ServerGenerated;

                    // if we changed it, we don't care what it was
                    if (updateHadProperty)
                    {
                        ComparePropertyValues(property, update, final, checkValue);
                    }
                    else if (merge)
                    {
                        ComparePropertyValues(property, original, final, checkValue);
                    }
                    else if (checkValue)
                    {
                        CompareResetProperty(property, final);
                    }
                }
                else
                {
                    // dynamic property
                    if (updateHadProperty)
                    {
                        if (!finalHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Final version of entity is missing dynamic property '" + propertyName + "'");
                        }
                        CompareDynamicPropertyValues(update, final);
                    }
                    else if (merge)
                    {
                        if (!finalHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Final version of entity is missing dynamic property '" + propertyName + "'");
                        }
                        CompareDynamicPropertyValues(original, final);
                    }
                    else if (finalHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Dynamic property '" + propertyName + "' was not cleared after reset");
                    }
                }
            }
        }