Beispiel #1
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);
        }
Beispiel #2
0
        protected bool EquivalentValues(NodeType firstType, PayloadProperty first, NodeType secondType, PayloadProperty second)
        {
            PayloadSimpleProperty firstSimple  = first as PayloadSimpleProperty;
            PayloadSimpleProperty secondSimple = second as PayloadSimpleProperty;

            if (firstSimple == null || secondSimple == null)
            {
                return(false);
            }

            if ((firstType == Clr.Types.Double || firstType == Clr.Types.Float))
            {
                if (second.ParentObject.Format == SerializationFormatKind.JSON)
                {
                    if (secondType == Clr.Types.Int16 || secondType == Clr.Types.Int32 || secondType == Clr.Types.Int64)
                    {
                        if (((long)double.Parse(firstSimple.Value)) == long.Parse(secondSimple.Value))
                        {
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Beispiel #3
0
        protected void CompareDynamicPropertyValues(PayloadProperty inserted, PayloadProperty returned)
        {
            if (inserted.IsNull || returned.IsNull)
            {
                if (!inserted.IsNull)
                {
                    AstoriaTestLog.FailAndThrow("Null inserted value was non-null in return payload");
                }
                if (!returned.IsNull)
                {
                    AstoriaTestLog.FailAndThrow("Non-null inserted value was null in return payload");
                }
            }
            else
            {
                NodeType insertType = GetDynamicPropertyType(inserted);
                NodeType returnType = GetDynamicPropertyType(returned);

                if (inserted.MappedOutOfContent == returned.MappedOutOfContent)
                {
                    bool equivalentTypes = false;
                    if (EquivalentValues(insertType, inserted, returnType, returned))
                    {
                        equivalentTypes = true;
                    }
                    if (EquivalentValues(returnType, returned, insertType, inserted))
                    {
                        equivalentTypes = true;
                    }

                    if (!equivalentTypes)
                    {
                        AstoriaTestLog.AreEqual(insertType, returnType, "Type of inserted/updated dynamic property value does not match returned type for property", false);
                    }
                }
                else if (inserted.MappedOutOfContent)
                {
                    insertType = returnType;
                }

                ComparePropertyValues(insertType, inserted, returned, true);
            }
        }
Beispiel #4
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 + "'");
                            }
                        }
                    }
                }
            }
        }
Beispiel #5
0
        protected void ComparePropertyValues(NodeType type, PayloadProperty first, PayloadProperty second, bool checkValue)
        {
            if (type is ComplexType)
            {
                if (first.IsNull)
                {
                    if (!second.IsNull)
                    {
                        AstoriaTestLog.FailAndThrow("Second property is unexpectedly non-null");
                    }
                    return;
                }
                else if (second.IsNull)
                {
                    AstoriaTestLog.FailAndThrow("Second property is unexpectedly null");
                }

                PayloadComplexProperty firstComplex  = first as PayloadComplexProperty;
                PayloadComplexProperty secondComplex = second as PayloadComplexProperty;

                if (firstComplex == null)
                {
                    AstoriaTestLog.FailAndThrow("First property was not a complex property");
                }
                if (secondComplex == null)
                {
                    AstoriaTestLog.FailAndThrow("Second property was not a complex property");
                }

                foreach (string propertyName in firstComplex.PayloadProperties.Keys.Union(secondComplex.PayloadProperties.Keys))
                {
                    // TODO: verify typing
                    if (propertyName == "__metadata")
                    {
                        continue;
                    }

                    PayloadProperty firstProperty;
                    bool            firstHadProperty = firstComplex.PayloadProperties.TryGetValue(propertyName, out firstProperty);

                    PayloadProperty secondProperty;
                    bool            secondHadProperty = secondComplex.PayloadProperties.TryGetValue(propertyName, out secondProperty);

                    // so that we can ignore this case later on, check it now
                    if (!firstHadProperty && !secondHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Property list contained property '" + propertyName + "' despite neither complex property containing it");
                    }

                    // since a complex type is never open, there shouldnt be any unexpected properties
                    NodeProperty property = (type as ComplexType).Properties.SingleOrDefault(p => p.Name == propertyName);
                    if (property == null)
                    {
                        if (firstHadProperty && secondHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Both complex properties contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        }
                        else if (firstHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("First complex property contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        }
                        else if (secondHadProperty)
                        {
                            AstoriaTestLog.FailAndThrow("Second complex property contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        }
                    }

                    if (!firstHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("First complex property property missing sub-property '" + propertyName + "'");
                    }
                    else if (!secondHadProperty)
                    {
                        AstoriaTestLog.FailAndThrow("Second complex property property missing sub-property '" + propertyName + "'");
                    }

                    ComparePropertyValues(property, firstProperty, secondProperty, checkValue && !property.Facets.ServerGenerated);
                }
            }
            else
            {
                PayloadSimpleProperty firstSimple  = first as PayloadSimpleProperty;
                PayloadSimpleProperty secondSimple = second as PayloadSimpleProperty;

                if (firstSimple == null)
                {
                    AstoriaTestLog.FailAndThrow("First property was not a simple property");
                }
                if (secondSimple == null)
                {
                    AstoriaTestLog.FailAndThrow("Second property was not a simple property");
                }

                object expectedObject = CommonPayload.DeserializeStringToObject(firstSimple.Value, type.ClrType, false, first.ParentObject.Format);
                if (checkValue)
                {
                    CommonPayload.ComparePrimitiveValuesObjectAndString(expectedObject, type.ClrType, secondSimple.Value, false, second.ParentObject.Format, true);
                }
                else
                {
                    CommonPayload.DeserializeStringToObject(secondSimple.Value, type.ClrType, false, second.ParentObject.Format);
                }
            }
        }
Beispiel #6
0
 protected void ComparePropertyValues(NodeProperty property, PayloadProperty first, PayloadProperty second, bool checkValue)
 {
     // in case we need to do any facet-based logic
     ComparePropertyValues(property.Type, first, second, checkValue);
 }
Beispiel #7
0
        protected NodeType GetDynamicPropertyType(PayloadProperty property)
        {
            string typeName = property.Type;

            if (typeName == null)
            {
                if (property.ParentObject.Format == SerializationFormatKind.JSON)
                {
                    if (property is PayloadComplexProperty)
                    {
                        PayloadComplexProperty complexProperty = property as PayloadComplexProperty;
                        PayloadProperty        metadata;
                        if (!complexProperty.PayloadProperties.TryGetValue("__metadata", out metadata) || !(metadata is PayloadComplexProperty))
                        {
                            AstoriaTestLog.FailAndThrow("Complex type properties did not contain __metadata complex property");
                        }
                        PayloadProperty metadataType;
                        if (!(metadata as PayloadComplexProperty).PayloadProperties.TryGetValue("type", out metadataType) || !(metadataType is PayloadSimpleProperty))
                        {
                            AstoriaTestLog.FailAndThrow("__metadata property did not contain complex type's name");
                        }
                        typeName = (metadataType as PayloadSimpleProperty).Value;
                    }

                    if (typeName == null)
                    {
                        typeName = "String";
                    }
                }
                else
                {
                    typeName = "String";
                }
            }
            else if (typeName.StartsWith("Edm."))
            {
                typeName = typeName.Replace("Edm.", null);
            }

            if (typeName == "Binary")
            {
                typeName = "Byte[]";
            }

            // json datetime check
            if (typeName == "String" && property.ParentObject.Format == SerializationFormatKind.JSON && property is PayloadSimpleProperty)
            {
                PayloadSimpleProperty simpleProperty = property as PayloadSimpleProperty;
                if (Util.JsonPrimitiveTypesUtil.DateTimeRegex.IsMatch(simpleProperty.Value))
                {
                    typeName = "DateTime";
                }
            }

            NodeType type = Clr.Types.SingleOrDefault(t => t.Name.Equals(typeName));

            if (type == null)
            {
                type = Response.Workspace.ServiceContainer.ComplexTypes.SingleOrDefault(ct => typeName.Equals(ct.Namespace + "." + ct.Name));
            }

            if (type == null)
            {
                AstoriaTestLog.FailAndThrow("Could not find type '" + typeName + "'");
            }

            return(type);
        }
Beispiel #8
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);
        }
Beispiel #9
0
 protected void ComparePropertyValues(NodeProperty property, PayloadProperty first, PayloadProperty second, bool checkValue)
 {
     // in case we need to do any facet-based logic
     ComparePropertyValues(property.Type, first, second, checkValue);
 }
Beispiel #10
0
        protected void ComparePropertyValues(NodeType type, PayloadProperty first, PayloadProperty second, bool checkValue)
        {
            if (type is ComplexType)
            {
                if(first.IsNull)
                {
                    if (!second.IsNull)
                        AstoriaTestLog.FailAndThrow("Second property is unexpectedly non-null");
                    return;
                }
                else if(second.IsNull)
                    AstoriaTestLog.FailAndThrow("Second property is unexpectedly null");

                PayloadComplexProperty firstComplex = first as PayloadComplexProperty;
                PayloadComplexProperty secondComplex = second as PayloadComplexProperty;

                if (firstComplex == null)
                    AstoriaTestLog.FailAndThrow("First property was not a complex property");
                if( secondComplex == null)
                    AstoriaTestLog.FailAndThrow("Second property was not a complex property");

                foreach (string propertyName in firstComplex.PayloadProperties.Keys.Union(secondComplex.PayloadProperties.Keys))
                {
                    // TODO: verify typing
                    if (propertyName == "__metadata")
                        continue;

                    PayloadProperty firstProperty;
                    bool firstHadProperty = firstComplex.PayloadProperties.TryGetValue(propertyName, out firstProperty);

                    PayloadProperty secondProperty;
                    bool secondHadProperty = secondComplex.PayloadProperties.TryGetValue(propertyName, out secondProperty);

                    // so that we can ignore this case later on, check it now
                    if (!firstHadProperty && !secondHadProperty)
                        AstoriaTestLog.FailAndThrow("Property list contained property '" + propertyName + "' despite neither complex property containing it");

                    // since a complex type is never open, there shouldnt be any unexpected properties
                    NodeProperty property = (type as ComplexType).Properties.SingleOrDefault(p => p.Name == propertyName);
                    if (property == null)
                    {
                        if (firstHadProperty && secondHadProperty)
                            AstoriaTestLog.FailAndThrow("Both complex properties contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        else if(firstHadProperty)
                            AstoriaTestLog.FailAndThrow("First complex property contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                        else if (secondHadProperty)
                            AstoriaTestLog.FailAndThrow("Second complex property contained sub-property '" + propertyName + "' which is not defined on type '" + type.Name + "'");
                    }

                    if (!firstHadProperty)
                        AstoriaTestLog.FailAndThrow("First complex property property missing sub-property '" + propertyName + "'");
                    else if (!secondHadProperty)
                        AstoriaTestLog.FailAndThrow("Second complex property property missing sub-property '" + propertyName + "'");

                    ComparePropertyValues(property, firstProperty, secondProperty, checkValue && !property.Facets.ServerGenerated);
                }
            }
            else
            {
                PayloadSimpleProperty firstSimple = first as PayloadSimpleProperty;
                PayloadSimpleProperty secondSimple = second as PayloadSimpleProperty;

                if (firstSimple == null)
                    AstoriaTestLog.FailAndThrow("First property was not a simple property");
                if (secondSimple == null)
                    AstoriaTestLog.FailAndThrow("Second property was not a simple property");

                object expectedObject = CommonPayload.DeserializeStringToObject(firstSimple.Value, type.ClrType, false, first.ParentObject.Format);
                if (checkValue)
                    CommonPayload.ComparePrimitiveValuesObjectAndString(expectedObject, type.ClrType, secondSimple.Value, false, second.ParentObject.Format, true);
                else
                    CommonPayload.DeserializeStringToObject(secondSimple.Value, type.ClrType, false, second.ParentObject.Format);
            }
        }
Beispiel #11
0
        protected NodeType GetDynamicPropertyType(PayloadProperty property)
        {
            string typeName = property.Type;
            if(typeName == null)
            {
                if (property.ParentObject.Format == SerializationFormatKind.JSON)
                {
                    if (property is PayloadComplexProperty)
                    {
                        PayloadComplexProperty complexProperty = property as PayloadComplexProperty;
                        PayloadProperty metadata;
                        if (!complexProperty.PayloadProperties.TryGetValue("__metadata", out metadata) || !(metadata is PayloadComplexProperty))
                            AstoriaTestLog.FailAndThrow("Complex type properties did not contain __metadata complex property");
                        PayloadProperty metadataType;
                        if(!(metadata as PayloadComplexProperty).PayloadProperties.TryGetValue("type", out metadataType) || !(metadataType is PayloadSimpleProperty))
                            AstoriaTestLog.FailAndThrow("__metadata property did not contain complex type's name");
                        typeName = (metadataType as PayloadSimpleProperty).Value;
                    }

                    if(typeName == null)
                    {
                        typeName = "String";
                    }
                }
                else
                {
                    typeName = "String";
                }
            }
            else if (typeName.StartsWith("Edm."))
            {
                typeName = typeName.Replace("Edm.", null);
            }

            if (typeName == "Binary")
                typeName = "Byte[]";

            // json datetime check
            if (typeName == "String" && property.ParentObject.Format == SerializationFormatKind.JSON && property is PayloadSimpleProperty)
            {
                PayloadSimpleProperty simpleProperty = property as PayloadSimpleProperty;
                if (Util.JsonPrimitiveTypesUtil.DateTimeRegex.IsMatch(simpleProperty.Value))
                    typeName = "DateTime";
            }

            NodeType type = Clr.Types.SingleOrDefault(t => t.Name.Equals(typeName));
            
            if (type == null)
                type = Response.Workspace.ServiceContainer.ComplexTypes.SingleOrDefault(ct => typeName.Equals(ct.Namespace + "." + ct.Name));
            
            if (type == null)
                AstoriaTestLog.FailAndThrow("Could not find type '" + typeName + "'");
            
            return type;
        }
Beispiel #12
0
        protected bool EquivalentValues(NodeType firstType, PayloadProperty first, NodeType secondType, PayloadProperty second)
        {
            PayloadSimpleProperty firstSimple = first as PayloadSimpleProperty;
            PayloadSimpleProperty secondSimple = second as PayloadSimpleProperty;

            if (firstSimple == null || secondSimple == null)
                return false;

            if ((firstType == Clr.Types.Double || firstType == Clr.Types.Float))
            {
                if (second.ParentObject.Format == SerializationFormatKind.JSON)
                {
                    if (secondType == Clr.Types.Int16 || secondType == Clr.Types.Int32 || secondType == Clr.Types.Int64)
                    {
                        if (((long)double.Parse(firstSimple.Value)) == long.Parse(secondSimple.Value))
                            return true;
                    }
                }
            }
            return false;
        }
Beispiel #13
0
        protected void CompareDynamicPropertyValues(PayloadProperty inserted, PayloadProperty returned)
        {
            if (inserted.IsNull || returned.IsNull)
            {
                if (!inserted.IsNull)
                    AstoriaTestLog.FailAndThrow("Null inserted value was non-null in return payload");
                if (!returned.IsNull)
                    AstoriaTestLog.FailAndThrow("Non-null inserted value was null in return payload");
            }
            else
            {
                NodeType insertType = GetDynamicPropertyType(inserted);
                NodeType returnType = GetDynamicPropertyType(returned);

                if (inserted.MappedOutOfContent == returned.MappedOutOfContent)
                {
                    bool equivalentTypes = false;
                    if (EquivalentValues(insertType, inserted, returnType, returned))
                        equivalentTypes = true;
                    if (EquivalentValues(returnType, returned, insertType, inserted))
                        equivalentTypes = true;

                    if (!equivalentTypes)
                        AstoriaTestLog.AreEqual(insertType, returnType, "Type of inserted/updated dynamic property value does not match returned type for property", false);
                }
                else if(inserted.MappedOutOfContent)
                {
                    insertType = returnType;
                }

                ComparePropertyValues(insertType, inserted, returned, true);
            }
        }
Beispiel #14
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");
                    }
                }
            }
        }
Beispiel #15
0
        private void CompareResetProperty(NodeProperty property, PayloadProperty value)
        {
            bool complexType = property.Type is ComplexType;

            Workspace w          = value.ParentObject.Payload.Workspace;
            bool      expectNull = false;

            if (w.DataLayerProviderKind == DataLayerProviderKind.NonClr && (!property.Facets.IsClrProperty || complexType))
            {
                expectNull = true;
            }
            if (w.DataLayerProviderKind == DataLayerProviderKind.InMemoryLinq && complexType)
            {
                expectNull = true;
            }
            if (!property.Facets.IsDeclaredProperty)
            {
                expectNull = true;
            }
            if (property.Facets.Nullable)
            {
                expectNull = true;
            }

            if (property.Type is ComplexType)
            {
                if (value.IsNull)
                {
                    if (!expectNull)
                    {
                        AstoriaTestLog.FailAndThrow("Complex property '" + property.Name + " is unexpectedly null after reset");
                    }
                }
                else
                {
                    if (!(value is PayloadComplexProperty))
                    {
                        AstoriaTestLog.FailAndThrow("Property '" + property.Name + "' is complex, but a simple property was found instead");
                    }

                    ComplexType            ct = property.Type as ComplexType;
                    PayloadComplexProperty complexProperty = value as PayloadComplexProperty;
                    foreach (NodeProperty subProperty in ct.Properties)
                    {
                        PayloadProperty subValue;
                        if (!complexProperty.PayloadProperties.TryGetValue(subProperty.Name, out subValue))
                        {
                            AstoriaTestLog.FailAndThrow("Property of complex type '" + ct.Name + "' missing sub-property '" + subProperty.Name + "'");
                        }

                        CompareResetProperty(subProperty, subValue);
                    }
                }
            }
            else
            {
                PayloadSimpleProperty simpleProperty = value as PayloadSimpleProperty;
                if (simpleProperty == null)
                {
                    AstoriaTestLog.FailAndThrow("Property was unexpectedly not a simple property");
                }

                Type   propertyType = property.Type.ClrType;
                object expected     = null;
                if (!expectNull)
                {
                    expected = DefaultValue(propertyType);
                }
                CommonPayload.ComparePrimitiveValuesObjectAndString(expected, propertyType, simpleProperty.Value, false, value.ParentObject.Format, true);
            }
        }