Esempio n. 1
0
        private static void VerifyLinksPayload(Workspace w, CommonPayload payload, LinqQueryBuilder linqBuilder)
        {
            ArrayList expectedEntities = CommonPayload.CreateList(linqBuilder.QueryResult);

            if (payload == null)
            {
                AstoriaTestLog.AreEqual(expectedEntities.Count, 0, "Unexpected null $ref payload");
            }
            else
            {
                KeyExpressions expectedKeys = new KeyExpressions();
                foreach (object o in expectedEntities)
                {
                    KeyExpression keyExp = w.CreateKeyExpressionFromProviderObject(o);
                    expectedKeys.Add(keyExp);
                }

                List <string> linksFound = new List <string>();

                if (payload.Resources == null)
                {
                    linksFound.Add(payload.Value);
                }
                else
                {
                    foreach (PayloadObject o in (payload.Resources as List <PayloadObject>))
                    {
                        if (o.PayloadProperties.Any(p => p.Name == "uri"))
                        {
                            linksFound.Add((o["uri"] as PayloadSimpleProperty).Value);
                        }
                    }
                }

                AstoriaTestLog.AreEqual(expectedKeys.Count, linksFound.Count, "Number of expected entities does not match number of links found");

                foreach (string link in linksFound)
                {
                    KeyExpression match = null;
                    foreach (KeyExpression expectedKey in expectedKeys)
                    {
                        if (compareKeyURI(link, expectedKey))
                        {
                            match = expectedKey;
                            break;
                        }
                    }

                    if (match != null)
                    {
                        expectedKeys.Remove(match);
                    }
                    else
                    {
                        AstoriaTestLog.WriteLineIgnore("Unexpected URI: '" + link + "'");
                        AstoriaTestLog.FailAndThrow("Unexpected URI found in $ref payload");
                    }
                }
            }
        }
Esempio n. 2
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));
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        public static void VerifyUnknownVerb(AstoriaResponse webResponse)
        {
            AstoriaTestLog.AreEqual(System.Net.HttpStatusCode.NotImplemented, webResponse.ActualStatusCode,
                                    "Unknown verbs should receive a 'Not Implemented' reply.");

            if (webResponse.ContentType != null)
            {
                AstoriaTestLog.IsTrue(webResponse.ContentType.StartsWith(SerializationFormatKinds.JsonMimeType, StringComparison.Ordinal),
                                      "Error messages should have no content type or an application/json content type.");
            }
        }
Esempio n. 5
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);
                }
            }
        }
Esempio n. 6
0
            public void Add(ContainmentAttribute att, bool abbrChild)
            {
                ContainmentQuerySegment segment = new ContainmentQuerySegment(att, abbrChild);

                if (segments.Count == 0)
                {
                    AstoriaTestLog.AreEqual(segment.attribute.ParentContainer, rootContainer,
                                            "First segment's parent container does not match this path's root container");
                }
                else
                {
                    AstoriaTestLog.AreEqual(segment.attribute.ParentContainer, segments.Last().attribute.ChildContainer,
                                            "New segment's parent does not match the current last container");
                }
                segments.Add(segment);
            }
Esempio n. 7
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);
            }
        }
Esempio n. 8
0
        private static void CompareEntityContainer(IEdmEntityContainer edmEntityContainer, IEdmEntityContainer dataWebEntityContainer)
        {
            AstoriaTestLog.AreEqual(edmEntityContainer.FullName(), dataWebEntityContainer.FullName());

            int numberOfEntitySets = 0;

            foreach (IEdmEntitySet entitySetBase in edmEntityContainer.EntitySets())
            {
                // compare the entity set base
                IEdmEntitySet dataWebEntitySetBase = dataWebEntityContainer.FindEntitySet(entitySetBase.Name);

                AstoriaTestLog.IsNotNull(dataWebEntitySetBase);
                AstoriaTestLog.AreEqual(entitySetBase.Name, dataWebEntitySetBase.Name);
                AstoriaTestLog.AreEqual(entitySetBase.EntityType().FullName(), dataWebEntitySetBase.EntityType().FullName());

                ++numberOfEntitySets;
            }

            AstoriaTestLog.IsTrue(numberOfEntitySets == dataWebEntityContainer.EntitySets().Count(), "Number of baseEntitySets must match");
        }
Esempio n. 9
0
        public static void ComparePrimitiveValuesObjectAndString(object expected, Type expectedType, string actual, bool valueUri, SerializationFormatKind serializationKind, bool throwOnError)
        {
            object actualObject = DeserializeStringToObject(actual, expectedType, valueUri, serializationKind);
            string expectedStr  = "null";

            if (expected != null)
            {
                expectedStr = AstoriaUnitTests.Data.TypeData.XmlValueFromObject(expected);
            }

            string errorMessage = String.Format("Error Primitive Value of type:{0} not equal: \r\n\tExpected:\t{1} \r\n\tActual:\t{2}", expectedType.Name, expectedStr, actual);

            //Fixups
            if (expected != null && expectedType.Equals(typeof(string)))
            {
                if (actualObject != null)
                {
                    actualObject = (actualObject as string).Trim();
                }
                expected = (expected as string).Trim();
            }

            if (expectedType == typeof(System.Xml.Linq.XElement))
            {
                expectedStr = null;
                if (expected != null)
                {
                    System.Xml.Linq.XElement xElement = expected as System.Xml.Linq.XElement;
                    expectedStr = xElement.ToString();
                }
                AstoriaTestLog.AreEqual(expectedStr, actual, errorMessage);
            }
            else if (expectedType == typeof(Single) || expectedType == typeof(Double))
            {
                if (serializationKind == SerializationFormatKind.JSON)
                {
                    if (expectedType == typeof(Double))
                    {
                        Double d;
                        if (expected != null)
                        {
                            d           = Convert.ToDouble(expected);
                            expectedStr = d.ToString("r", System.Globalization.CultureInfo.InvariantCulture);
                        }
                        if (actual != null)
                        {
                            if (double.TryParse(actual, NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out d))
                            {
                                actual = d.ToString("r", CultureInfo.InvariantCulture.NumberFormat);
                            }
                        }
                    }
                    else if (expectedType == typeof(Single))
                    {
                        Single s;
                        if (expected != null)
                        {
                            s           = Convert.ToSingle(expected);
                            expectedStr = s.ToString("r", System.Globalization.CultureInfo.InvariantCulture);
                        }
                        if (actual != null)
                        {
                            if (Single.TryParse(actual, NumberStyles.Any, CultureInfo.InvariantCulture.NumberFormat, out s))
                            {
                                actual = s.ToString("r", CultureInfo.InvariantCulture.NumberFormat);
                            }
                        }
                    }
                }
                //Fixup
                if (expectedStr == "null")
                {
                    expectedStr = null;
                }
                if (expectedStr != null && actual != null)
                {
                    expectedStr = expectedStr.Trim();
                    actual      = actual.Trim();
                }
                if (throwOnError)
                {
                    if (expectedStr != null)
                    {
                        AstoriaTestLog.Compare(expectedStr.Equals(actual), errorMessage);
                    }
                    else
                    {
                        AstoriaTestLog.Compare(actual == null, errorMessage);
                    }
                }
                else
                {
                    AstoriaTestLog.AreEqual(expectedStr, actual, errorMessage);
                }
            }
#if !ClientSKUFramework
            //For some reason byte[] comparision is not working correctly
            else if ((expectedType == typeof(byte[]) || expectedType == typeof(System.Data.Linq.Binary)) && valueUri)
            {
                string expectedBytesStr = null;
                if (expected == null)
                {
                    expectedBytesStr = null;
                }
                else if (expectedType == typeof(byte[]))
                {
                    expectedBytesStr = (new System.Text.UTF8Encoding()).GetString((byte[])expected);
                }


                else if (expectedType == typeof(System.Data.Linq.Binary))
                {
                    System.Data.Linq.Binary binary = expected as System.Data.Linq.Binary;
                    expectedBytesStr = (new System.Text.UTF8Encoding()).GetString((byte[])binary.ToArray());
                }

                if (throwOnError)
                {
                    if (expected == null)
                    {
                        AstoriaTestLog.Compare(null == actual, errorMessage);
                    }
                    else
                    {
                        AstoriaTestLog.Compare(expectedBytesStr.Equals(actual), errorMessage);
                    }
                }
                else
                {
                    AstoriaTestLog.AreEqual(expectedBytesStr, actual, errorMessage);
                }
            }
#endif

            else if (expectedType == typeof(byte[]) && valueUri == false)
            {
                AreBytesEqual((byte[])expected, (byte[])actualObject, throwOnError);
            }
            else
            {
                if (throwOnError)
                {
                    bool objectsEqual = true;
                    if (expected == null)
                    {
                        if (actualObject != null)
                        {
                            objectsEqual = false;
                        }
                    }
                    else
                    {
                        objectsEqual = expected.Equals(actualObject);
                    }
                    AstoriaTestLog.Compare(objectsEqual, errorMessage);
                }
                else
                {
                    AstoriaTestLog.AreEqual(expected, actualObject, errorMessage);
                }
            }
        }
Esempio n. 10
0
        private static void AreBytesEqual(byte[] expected, byte[] actual, bool throwOnError)
        {
            if (expected == null && actual == null)
            {
                return;
            }
            else if (expected == null && actual != null)
            {
                if (throwOnError)
                {
                    AstoriaTestLog.Compare(false, "Expected Actual to be null like expected");
                }
                else
                {
                    AstoriaTestLog.AreEqual(expected, actual, "Bytes not equal");
                }
                return;
            }
            else if (expected != null && actual == null)
            {
                if (throwOnError)
                {
                    AstoriaTestLog.Compare(false, "Expected Actual to be a value like expected");
                }
                else
                {
                    AstoriaTestLog.AreEqual(expected, actual, "Bytes not equal");
                }
                return;
            }
            if (throwOnError)
            {
                AstoriaTestLog.Compare(expected.Length == actual.Length, "Bytes lengths are not equal");
            }
            else
            {
                AstoriaTestLog.AreEqual(expected.Length, actual.Length, "Bytes lengths are not equal");
            }
            bool errorFound = false;

            for (int i = 0; i < expected.Length; i++)
            {
                if (expected[i] != actual[i])
                {
                    errorFound = true;
                    string errorMessage = String.Format("Byte arrays not equal at index {0}, expected:{1} actual:{2}", i, expected[i], actual[i]);
                    if (throwOnError)
                    {
                        AstoriaTestLog.Compare(expected[i] == actual[i], errorMessage);
                    }
                    else
                    {
                        AstoriaTestLog.AreEqual(expected.Length, actual.Length, errorMessage);
                    }
                }
                if (errorFound == true)
                {
                    break;
                }
            }
        }
Esempio n. 11
0
        public static void CompareMetadata(IEdmModel expectedItems, IEdmModel actualItems, bool isReflectionBasedProvider, string defaultEntityContainerName, ServiceContainer serviceContainer)
        {
            //
            //  Verify the metadata version is correct, the number of entity containers is 1, the entity
            //  container names match, and the number of entity types are the same
            //
            AstoriaTestLog.AreEqual(1.1, actualItems.GetEdmVersion(), "The metadata version was not correct");
            AstoriaTestLog.AreEqual(serviceContainer.Workspace.ContextTypeName, actualItems.EntityContainer.Name, "Entity Container names do not match");
            if (!isReflectionBasedProvider)
            {
                AstoriaTestLog.AreEqual(expectedItems.SchemaElements.OfType <IEdmEntityType>().Count(), actualItems.SchemaElements.OfType <IEdmEntityType>().Count(), "Entity Type Counts do not match");
            }

            foreach (IEdmOperationImport metadataExposedFunction in actualItems.EntityContainer.OperationImports())
            {
                AstoriaTestLog.TraceInfo("--> " + metadataExposedFunction.Name);
            }

            //
            //  For each entity type exposed through the metadata endpoint, verify the following
            //      1.  Verify it has an equivalent definition in the resource container
            //      2.  Verify the entity type name is correct
            //      3.  Verify that no navigation property is exposed in the entity type
            //      4.  Verify that the property count in the entity type
            //
            IEnumerable <ComplexType> rtTypeCollection = serviceContainer.AllTypes.Where(a => a.GetType().Name.Equals("ResourceType"));

            AstoriaTestLog.TraceInfo(rtTypeCollection.Count().ToString());

            foreach (IEdmEntityType metadataExposedEntityType in actualItems.SchemaElements.OfType <IEdmEntityType>())
            {
                ResourceType resourceContainerEntityType = serviceContainer.AllTypes.Where(b => b.GetType().Name.Equals("ResourceType") & (b.FullName.Equals(metadataExposedEntityType.FullName()))).FirstOrDefault() as ResourceType;
                if (resourceContainerEntityType == null)
                {
                    continue;
                }

                AstoriaTestLog.IsNotNull(resourceContainerEntityType, "Did not find entity type in resource container");
                AstoriaTestLog.AreEqual(resourceContainerEntityType.FullName, metadataExposedEntityType.FullName(), "Entity Type name mismatch");

                //
                //  Verify the name, type, and nullable attribute values
                //
                ResourceContainer rc = serviceContainer.ResourceContainers.Where(a => a.BaseType.Name.Equals(metadataExposedEntityType.Name)).FirstOrDefault();
                if (rc == null)
                {
                    continue;
                }
                int navCount = rc.BaseType.Properties.Cast <NodeProperty>().Cast <ResourceProperty>().Where(a => a.IsNavigation).Count();

                AstoriaTestLog.TraceInfo(rc.Name);
                AstoriaTestLog.TraceInfo(navCount.ToString());
                AstoriaTestLog.AreEqual(resourceContainerEntityType.Properties.Count - navCount, metadataExposedEntityType.Properties().Count(), "Edm Property count mismatch");
                foreach (IEdmProperty metadataExposedProperty in metadataExposedEntityType.Properties())
                {
                    string errorStringEntityTypeProperty = metadataExposedEntityType.FullName() + " : " + metadataExposedProperty.Name;

                    NodeProperty resourceContainerProperty = resourceContainerEntityType.Properties.Where(a => a.Name.Equals(metadataExposedProperty.Name)).FirstOrDefault();
                    AstoriaTestLog.IsNotNull(resourceContainerProperty, "Did not find property -->" + errorStringEntityTypeProperty + "<-- in resource container");
                    if (resourceContainerProperty == null)
                    {
                        continue;
                    }

                    if (metadataExposedProperty.Type.IsBinary())
                    {
                        if (AstoriaTestProperties.DataLayerProviderKinds.Contains(DataLayerProviderKind.LinqToSql))
                        {
                            AstoriaTestLog.AreEqual("System.Data.Linq.Binary", resourceContainerProperty.Type.ClrType.FullName, errorStringEntityTypeProperty + " type is incorrect");
                        }
                        else
                        {
                            AstoriaTestLog.AreEqual("System.Byte[]", resourceContainerProperty.Type.ClrType.FullName, errorStringEntityTypeProperty + " type is incorrect");
                        }
                    }
                    else
                    {
                        AstoriaTestLog.AreEqual(metadataExposedProperty.Type.FullName(), resourceContainerProperty.Type.FullName, errorStringEntityTypeProperty + " type is incorrect");
                    }
                }
            }
        }
Esempio n. 12
0
 public static void AreEqual(object expected, object actual)
 {
     AstoriaTestLog.AreEqual(expected, actual, "", true);
 }
Esempio n. 13
0
        public void Verify(AstoriaResponse response)
        {
            string payload = response.Payload;

            XmlNodeList childNodes = null;

            XmlNode xmlData = FormatVerifyUtils.FindFirstChild(payload);

            if (xmlData.Name == "feed")
            {
                /* atom:feed elements MUST contain one or more atom:author elements,
                 *  unless all of the atom:feed element's child atom:entry elements
                 *  contain at least one atom:author element.
                 */
                childNodes = xmlData.SelectNodes("atom:author", _formatVerifier.XmlNamespaceManager);
                XmlNodeList entries = xmlData.SelectNodes("atom:entry", _formatVerifier.XmlNamespaceManager);

                if (childNodes.Count == 0)
                {
                    if (entries.Count > 0)
                    {
                        foreach (XmlNode node in entries)
                        {
                            XmlNode authorNode = node.SelectSingleNode("atom:author[1]", _formatVerifier.XmlNamespaceManager);
                            if (authorNode == null)
                            {
                                AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: No author node in entry of feed without author node."));
                            }
                        }
                    }
                    else
                    {
                        AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: No author node in feed with no entries."));
                    }
                }

                // atom:feed elements MUST NOT contain more than one atom:generator element.
                childNodes = xmlData.SelectNodes("atom:generator", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count > 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 generator node found for feed."));
                }

                // atom:feed elements MUST NOT contain more than one atom:icon element.
                childNodes = xmlData.SelectNodes("atom:icon", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count > 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 icon node found for feed."));
                }

                // atom:feed elements MUST NOT contain more than one atom:logo element.
                childNodes = xmlData.SelectNodes("atom:logo", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count > 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 logo node found for feed."));
                }

                // atom:feed elements MUST contain exactly one atom:id element
                childNodes = xmlData.SelectNodes("atom:id", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count != 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: Not exactly 1 id node found for feed."));
                }

                /* atom:feed elements SHOULD contain one atom:link element with a rel
                 *  attribute value of "self".  This is the preferred URI for
                 *  retrieving Atom Feed Documents representing this Atom feed.
                 *
                 * atom:feed elements MUST NOT contain more than one atom:link
                 *  element with a rel attribute value of "alternate" that has the
                 *  same combination of type and hreflang attribute values.
                 */
                int selfLinkCount = 0, altLinkCount = 0;
                childNodes = xmlData.SelectNodes("atom:link", _formatVerifier.XmlNamespaceManager);
                foreach (XmlNode node in childNodes)
                {
                    if (node.Attributes["rel"] != null && node.Attributes["rel"].Value == "self")
                    {
                        selfLinkCount++;
                    }
                    else if (node.Attributes["rel"] != null && node.Attributes["rel"].Value == "alternate")
                    {
                        altLinkCount++;
                    }
                }

                AstoriaTestLog.AreEqual(1, selfLinkCount, "4.1.1 Feed element: Not exactly 1 self link node found for feed");
                AstoriaTestLog.AreEqual(false, altLinkCount > 1, "4.1.1 Feed element: More than 1 alternate link node found for feed");

                // atom:feed elements MUST NOT contain more than one atom:rights element.
                childNodes = xmlData.SelectNodes("atom:rights", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count > 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 rights node found for feed."));
                }

                // atom:feed elements MUST NOT contain more than one atom:subtitle element.
                childNodes = xmlData.SelectNodes("atom:subtitle", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count > 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: More than 1 subtitle node found for feed."));
                }

                // atom:feed elements MUST contain exactly one atom:title element.
                childNodes = xmlData.SelectNodes("atom:title", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count != 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: Not exactly 1 title node found for feed."));
                }

                // atom:feed elements MUST contain exactly one atom:updated element.
                childNodes = xmlData.SelectNodes("atom:updated", _formatVerifier.XmlNamespaceManager);
                if (childNodes.Count != 1)
                {
                    AstoriaTestLog.FailAndContinue(new TestFailedException("4.1.1 Feed element: Not exactly 1 updated node found for feed."));
                }
            }
        }
Esempio n. 14
0
        public static void VerifyGet(AstoriaResponse response)
        {
            AstoriaRequest request = response.Request;

            if (request.Query != null)
            {
                LinqQueryBuilder linqBuilder = new LinqQueryBuilder(request.Workspace);
                linqBuilder.Build(request.Query);
                if (request.URI.Contains("$value"))
                {
                    CommonPayload payload;

                    // $value queries will sometimes return unexpected 404s due to null values
                    // if we get a 404 unexpectedly, the underlying result must be null
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NotFound)
                    {
                        payload = request.CommonPayload;
                    }

                    IEnumerable enumerable     = linqBuilder.QueryResult;
                    object      expectedResult = CommonPayload.GetSingleValueFromIQueryable(linqBuilder.QueryResult, false);

                    ResourceProperty rp = request.GetPropertyFromQuery();
                    CommonPayload.ComparePrimitiveValuesObjectAndString(expectedResult, rp.Type.ClrType, response.Payload, true, request.Format, false);
                }
                else if (request.URI.Contains("$count") || request.URI.Contains("$inlinecount"))
                {
                    if (request.URI.Contains("$count"))
                    {
                        // Versioning: make sure the server always returns 2.0.
                        VerifySpecificResponseVersion(response, 2, 0);

                        // PlainText payload.
                        try
                        {
                            VerifyStatusCode(response);
                            if (response.Request.ExpectedStatusCode == System.Net.HttpStatusCode.OK)
                            {
                                int countPayload  = Int32.Parse(response.Payload);
                                int countBaseline = CommonPayload.CreateList(linqBuilder.QueryResult).Count;
                                AstoriaTestLog.AreEqual(countPayload, countBaseline, "Counts in payload (" + countPayload + ") and baseline (" + countBaseline + ") differ.");
                            }
                        }
                        catch (TestFailedException tfe)
                        {
                            //When the underlying resource has zero elements, the server now throws a 404 error , causing false negatives
                            ValidateCountException(response, request, tfe);
                        }
                    }
                    else
                    {
                        VerifySpecificResponseVersion(response, 2, 0);

                        try
                        {
                            // JSON, Atom or PlainXml ($ref) payload.
                            VerifyStatusCode(response);
                            if (response.Request.ExpectedStatusCode == System.Net.HttpStatusCode.OK)
                            {
                                CommonPayload    payload             = response.CommonPayload;
                                LinqQueryBuilder baselineLinqBuilder = new LinqQueryBuilder(request.Workspace);
                                baselineLinqBuilder.CountingMode = true;
                                baselineLinqBuilder.Build(request.Query);

                                object baselineElementsCount = CommonPayload.CreateList(baselineLinqBuilder.QueryResult).Count;
                                payload.CompareCountInline(linqBuilder.QueryResult, baselineElementsCount);
                                AstoriaTestLog.WriteLine(linqBuilder.QueryExpression);
                                if (request.URI.Contains("$ref"))
                                {
                                    VerifyLinksPayload(request.Workspace, payload, linqBuilder);
                                }
                            }
                        }
                        catch (TestFailedException tfe)
                        {
                            //When the underlying resource has zero elements, the server now throws a 404 error , causing false negatives
                            ValidateCountException(response, request, tfe);
                        }
                    }
                }
                else
                {
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NoContent && response.Payload == "")
                    {
                        response.Payload = null; // allow result from Linq query and payload to be compared (NoContent is a get to a null Nav prop)
                    }
                    if (response.ActualStatusCode == System.Net.HttpStatusCode.NotFound)
                    {
                        return;
                    }

                    CommonPayload payload = response.CommonPayload;
                    if (request.URI.Contains("$ref"))
                    {
                        VerifyLinksPayload(request.Workspace, payload, linqBuilder);
                    }
                    else if (payload.Resources == null)
                    {
                        if (request.Format == SerializationFormatKind.JSON)
                        {
                            payload.CompareValue(linqBuilder.QueryResult, true, false);
                        }
                        else
                        {
                            payload.CompareValue(linqBuilder.QueryResult, false, false);
                        }
                    }
                    else
                    {
                        payload.Compare(linqBuilder.QueryResult);
                    }
                }
            }
        }
Esempio n. 15
0
 public static bool AreEqual(object expected, object actual, string message)
 {
     return(AstoriaTestLog.AreEqual(expected, actual, message, true));
 }
Esempio n. 16
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 + "'");
                            }
                        }
                    }
                }
            }
        }
Esempio n. 17
0
            public ContainmentQuery ToQuery(KeyExpression keyExpression, bool setOnly)
            {
                ResourceContainer finalContainer = FinalContainer;

                AstoriaTestLog.AreEqual(keyExpression.ResourceContainer, finalContainer,
                                        "ToQuery given a KeyExpression to an unexpected resource container");

                List <KeyExpression>     keys = GetContainingKeys(keyExpression);
                List <ResourceContainer> omittedContainers =
                    segments.Where(s => s.omitParent).Select(s => s.attribute.ParentContainer).ToList();

                ContainmentQuery query = new ContainmentQuery();

                query.Query       = null;
                query.Container   = finalContainer;
                query.Type        = query.Container.BaseType;
                query.Workspace   = query.Container.Workspace;
                query.SetExpected = setOnly;

                ResourceContainer parentContainer = null;

                foreach (KeyExpression key in keys)
                {
                    if (omittedContainers.Contains(key.ResourceContainer))
                    {
                        continue;
                    }

                    bool omitKey = (setOnly && key == keyExpression);

                    if (parentContainer == null)
                    {
                        if (!query.ErrorExpected && !key.ResourceContainer.BaseType.Facets.TopLevelAccess)
                        {
                            SetTopLevelAccessError(query, key.ResourceType);
                        }

                        if (!omitKey)
                        {
                            if (!query.ErrorExpected && key.IncludeInUri.Contains(false))
                            {
                                SetMissingKeysError(query, key.ResourceType);
                            }
                        }

                        query.Query = Query.From(Exp.Variable(key.ResourceContainer));
                    }
                    else
                    {
                        ResourceProperty navProp = segments
                                                   .Where(s => s.attribute.ParentContainer == parentContainer)
                                                   .Select(s => s.attribute.ParentNavigationProperty)
                                                   .FirstOrDefault();

                        query.Query = query.Query.Nav(navProp.Property());
                    }

                    parentContainer = key.ResourceContainer;

                    // if we just want the set, leave off the last where clause
                    if (!omitKey)
                    {
                        query.Query = query.Query.Where(key);
                    }
                }

                return(query);
            }
Esempio n. 18
0
        public static void Verify(Workspace w, ExpNode q, IEnumerable results, ResourceType resType, ComplexType cType, bool bCount)
        {
            long count = 0;

            if (bCount)
            {
                object[] args    = new object[] { results };
                Type     qorType = typeof(QueryOperationResponseWrapper <>).MakeGenericType(resType.ClientClrType);
                object   qor     = Activator.CreateInstance(qorType, args);

                PropertyInfo pi = qor.GetType().GetProperty("GetTotalCount");
                object       i  = pi.GetValue(qor, new object[] { });

                count = (long)i;

                LinqQueryBuilder lb = new LinqQueryBuilder(w);
                lb.CountingMode = true;
                lb.Build(q);

                object baselineElementsCount = CommonPayload.CreateList(lb.QueryResult).Count;
                AstoriaTestLog.IsTrue(count == Convert.ToInt64(baselineElementsCount), "Count is different.Count is " + count.ToString() + ". Baseline count is " + baselineElementsCount.ToString());
            }

            LinqQueryBuilder linqBuilder = new LinqQueryBuilder(w);

            linqBuilder.Build(q);

            IQueryable baselines = linqBuilder.QueryResult;

            IEnumerator b = null;

            IEnumerator r = null;

            try
            {
                b = TrustedMethods.IQueryableGetEnumerator(baselines);
                r = results.GetEnumerator();
            }
            catch (InvalidOperationException invalidOperation)
            {
                if (!AstoriaTestProperties.IsRemoteClient)
                {
                    throw invalidOperation;
                }
            }

            PropertyInfo propertyInfo    = null;
            Object       expectedResult1 = null;
            Object       expectedResult2 = null;

            try
            {
                while (b.MoveNext() && r.MoveNext())
                {
                    if (b.Current == null)
                    {
                        return;
                    }

                    if (r.Current == null)
                    {
                        throw new TestFailedException("Less results than expected");
                    }
                    //skip verification for Binary data type for Linq to Sql
                    if (AstoriaTestProperties.DataLayerProviderKinds[0] == DataLayerProviderKind.LinqToSql && b.Current is System.Byte[])
                    {
                        return;
                    }

                    if (b.Current is System.Byte[])
                    {
                        byte[] newBase = (byte[])b.Current;
                        byte[] newAct  = (byte[])r.Current;

                        if (newBase.Length != newAct.Length)
                        {
                            throw new TestFailedException("Failed to compare the results!");
                        }
                    }
#if !ClientSKUFramework
                    else if (b.Current is System.Data.Linq.Binary)
                    {
                        System.Data.Linq.Binary newBase = (System.Data.Linq.Binary)b.Current;
                        System.Data.Linq.Binary newAct  = new System.Data.Linq.Binary((byte[])r.Current);

                        if (newBase.Length != newAct.Length)
                        {
                            throw new TestFailedException("Failed to compare the results!");
                        }
                    }
#endif

                    else if (b.Current is System.Xml.Linq.XElement)
                    {
                        if (b.Current.ToString() != r.Current.ToString())
                        {
                            throw new TestFailedException("Failed to compare the results!");
                        }
                    }
                    else
                    {
                        if (!b.Current.Equals(r.Current))
                        {
                            if (cType != null)
                            {
                                foreach (ResourceProperty property in cType.Properties)
                                {
                                    if (!property.IsNavigation && !property.IsComplexType && !(property.Type is CollectionType))
                                    {
                                        propertyInfo    = b.Current.GetType().GetProperty(property.Name);
                                        expectedResult1 = propertyInfo.GetValue(b.Current, null);

                                        PropertyInfo propertyInfo2 = r.Current.GetType().GetProperty(property.Name);
                                        expectedResult2 = propertyInfo2.GetValue(r.Current, null);

                                        if (expectedResult1 != expectedResult2)
                                        {
                                            if (expectedResult1 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult1 = ((System.Xml.Linq.XElement)expectedResult1).ToString(System.Xml.Linq.SaveOptions.None);
                                            }
                                            if (expectedResult2 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult2 = ((System.Xml.Linq.XElement)expectedResult2).ToString(System.Xml.Linq.SaveOptions.None);
                                            }
                                            #if !ClientSKUFramework
                                            if (expectedResult1 is byte[])
                                            {
                                                expectedResult1 = new System.Data.Linq.Binary((byte[])expectedResult1);
                                            }

                                            if (expectedResult2 is byte[])
                                            {
                                                expectedResult2 = new System.Data.Linq.Binary((byte[])expectedResult2);
                                            }
                                            #endif


                                            AstoriaTestLog.AreEqual(expectedResult1, expectedResult2, String.Format("Resource value for {0} does not match", property.Name), false);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                foreach (ResourceProperty property in resType.Properties)
                                {
                                    if (!property.IsNavigation && !property.IsComplexType && !(property.Type is CollectionType))
                                    {
                                        //skip verification for Binary data type for Linq to Sql
                                        if (AstoriaTestProperties.DataLayerProviderKinds[0] == DataLayerProviderKind.LinqToSql && property.Type.Name == "LinqToSqlBinary")
                                        {
                                            return;
                                        }

                                        propertyInfo    = b.Current.GetType().GetProperty(property.Name);
                                        expectedResult1 = propertyInfo.GetValue(b.Current, null);

                                        PropertyInfo propertyinfo2 = r.Current.GetType().GetProperty(property.Name);
                                        expectedResult2 = propertyinfo2.GetValue(r.Current, null);

                                        if (expectedResult1 != expectedResult2)
                                        {
                                            if (expectedResult1 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult1 = ((System.Xml.Linq.XElement)expectedResult1).ToString(System.Xml.Linq.SaveOptions.None);
                                            }

                                            if (expectedResult2 is System.Xml.Linq.XElement)
                                            {
                                                expectedResult2 = ((System.Xml.Linq.XElement)expectedResult2).ToString(System.Xml.Linq.SaveOptions.None);
                                            }
                                            #if !ClientSKUFramework
                                            if (expectedResult1 is byte[])
                                            {
                                                expectedResult1 = new System.Data.Linq.Binary((byte[])expectedResult1);
                                            }

                                            if (expectedResult2 is byte[])
                                            {
                                                expectedResult2 = new System.Data.Linq.Binary((byte[])expectedResult2);
                                            }
                                            #endif
                                            AstoriaTestLog.AreEqual(expectedResult1, expectedResult2, String.Format("Resource value for {0} does not match", property.Name), false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                AstoriaTestLog.WriteLine(e.ToString());
                throw;
            }
        }
Esempio n. 19
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);
        }