예제 #1
0
        public void TestDomReadWriteResourceCreateWithPersonResource()
        {
            // Arrange
            var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes;

            var personResourceType       = serviceModel.GetResourceType <Person>();
            var personResourceIdentity   = personResourceType.ResourceIdentityInfo;
            var personFirstNameAttribute = personResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Person>(x => x.FirstName));
            var personLastNameAttribute  = personResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Person>(x => x.LastName));
            var personTwitterAttribute   = personResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Person>(x => x.Twitter));

            var expected = ApiSampleData.PersonResource;

            // Act
            var actual = DomReadWriteResource.Create(
                DomType.CreateFromResourceType(personResourceType),
                DomId.CreateFromApiResourceIdentity(personResourceType, expected),
                DomAttributes.Create(
                    DomAttribute.CreateFromApiResource(personFirstNameAttribute, expected),
                    DomAttribute.CreateFromApiResource(personLastNameAttribute, expected),
                    DomAttribute.CreateFromApiResource(personTwitterAttribute, expected)),
                DomReadWriteRelationships.Create(
                    DomReadWriteRelationship.Create(ApiSampleData.PersonToCommentsRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.PersonToRelationshipsToCommentsHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.PersonToCommentsHRef))))),
                DomReadWriteLinks.Create(
                    DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.PersonHRef))),
                DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta));

            this.OutputDomTree(actual);

            // Assert
            DomReadWriteResourceAssert.Equal(expected, actual);
        }
예제 #2
0
        public void TestDomReadWriteResourceCreateWithCommentResource()
        {
            // Arrange
            var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes;

            var commentResourceType     = serviceModel.GetResourceType <Comment>();
            var commentResourceIdentity = commentResourceType.ResourceIdentityInfo;
            var commentBodyAttribute    = commentResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Comment>(x => x.Body));

            var expected = ApiSampleData.CommentResource;

            // Act
            var actual = DomReadWriteResource.Create(
                DomType.CreateFromResourceType(commentResourceType),
                DomId.CreateFromApiResourceIdentity(commentResourceType, expected),
                DomAttributes.Create(
                    DomAttribute.CreateFromApiResource(commentBodyAttribute, expected)),
                DomReadWriteRelationships.Create(
                    DomReadWriteRelationship.Create(ApiSampleData.CommentToAuthorRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.CommentToRelationshipsToAuthorHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.CommentToAuthorHRef))))),
                DomReadWriteLinks.Create(
                    DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.CommentHRef))),
                DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta));

            this.OutputDomTree(actual);

            // Assert
            DomReadWriteResourceAssert.Equal(expected, actual);
        }
예제 #3
0
        public void TestDomReadWriteResourceCreateWithBlogResource()
        {
            // Arrange
            var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes;

            var blogResourceType     = serviceModel.GetResourceType <Blog>();
            var blogResourceIdentity = blogResourceType.ResourceIdentityInfo;
            var blogNameAttribute    = blogResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Blog>(x => x.Name));

            var expectedBlog = ApiSampleData.BlogResource;

            // Act
            var actual = DomReadWriteResource.Create(
                DomType.CreateFromResourceType(blogResourceType),
                DomId.CreateFromApiResourceIdentity(blogResourceType, expectedBlog),
                DomAttributes.Create(
                    DomAttribute.CreateFromApiResource(blogNameAttribute, expectedBlog)),
                DomReadWriteRelationships.Create(
                    DomReadWriteRelationship.Create(ApiSampleData.BlogToArticlesRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.BlogToRelationshipsToArticlesHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.BlogToArticlesHRef))))),
                DomReadWriteLinks.Create(
                    DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.BlogHRef))),
                DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta));

            this.OutputDomTree(actual);

            // Assert
            DomReadWriteResourceAssert.Equal(expectedBlog, actual);
        }
예제 #4
0
        public void TestDomReadWriteResourceCreateWithArticleResourceWithResourceLinkage()
        {
            // Arrange
            var serviceModel = ClrSampleData.ServiceModelWithBlogResourceTypes;

            var articleResourceType   = serviceModel.GetResourceType <Article>();
            var articleTitleAttribute = articleResourceType.GetClrAttributeInfo(StaticReflection.GetMemberName <Article>(x => x.Title));

            var commentResourceType = serviceModel.GetResourceType <Comment>();
            var personResourceType  = serviceModel.GetResourceType <Person>();

            var expectedArticle  = ApiSampleData.ArticleResourceWithResourceLinkage;
            var expectedAuthor   = ApiSampleData.PersonResource;
            var expectedComment1 = ApiSampleData.CommentResource1;
            var expectedComment2 = ApiSampleData.CommentResource2;

            // Act
            var actual = DomReadWriteResource.Create(
                DomType.CreateFromResourceType(articleResourceType),
                DomId.CreateFromApiResourceIdentity(articleResourceType, expectedArticle),
                DomAttributes.Create(
                    DomAttribute.CreateFromApiResource(articleTitleAttribute, expectedArticle)),
                DomReadWriteRelationships.Create(
                    DomReadWriteRelationship.Create(ApiSampleData.ArticleToAuthorRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleToRelationshipsToAuthorHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.ArticleToAuthorHRef))),
                                                    DomData.CreateFromResourceIdentifier(
                                                        DomReadWriteResourceIdentifier.Create(
                                                            DomType.CreateFromResourceType(personResourceType),
                                                            DomId.CreateFromApiResourceIdentity(personResourceType, expectedAuthor)))),
                    DomReadWriteRelationship.Create(ApiSampleData.ArticleToCommentsRel,
                                                    DomReadWriteLinks.Create(
                                                        DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleToRelationshipsToCommentsHRef)),
                                                        DomReadWriteLink.Create(Keywords.Related, DomHRef.Create(ApiSampleData.ArticleToCommentsHRef))),
                                                    DomDataCollection.CreateFromResourceIdentifiers(
                                                        DomReadWriteResourceIdentifier.Create(
                                                            DomType.CreateFromResourceType(commentResourceType),
                                                            DomId.CreateFromApiResourceIdentity(commentResourceType, expectedComment1)),
                                                        DomReadWriteResourceIdentifier.Create(
                                                            DomType.CreateFromResourceType(commentResourceType),
                                                            DomId.CreateFromApiResourceIdentity(commentResourceType, expectedComment2))))),
                DomReadWriteLinks.Create(
                    DomReadWriteLink.Create(Keywords.Canonical, DomHRef.Create(ApiSampleData.ArticleHRef)),
                    DomReadWriteLink.Create(Keywords.Self, DomHRef.Create(ApiSampleData.ArticleHRef))),
                DomReadOnlyMeta.Create(ApiSampleData.ResourceMeta));

            this.OutputDomTree(actual);

            // Assert
            DomReadWriteResourceAssert.Equal(expectedArticle, actual);
        }
        // PUBLIC METHODS ///////////////////////////////////////////////////
        #region Assert Methods
        public static void Equal(Relationships expected, DomReadWriteRelationships actual)
        {
            if (expected == null)
            {
                Assert.Null(actual);
                return;
            }
            Assert.NotNull(actual);

            Assert.Equal(DomNodeType.Relationships, actual.NodeType);

            var actualNodes = actual.Nodes()
                              .ToList();

            var actualDomRelationshipsCount = actualNodes.Count;

            Assert.Equal(expected.Count, actualDomRelationshipsCount);

            foreach (var expectedRelRelationshipPair in expected)
            {
                var expectedRel          = expectedRelRelationshipPair.Key;
                var expectedRelationship = expectedRelRelationshipPair.Value;

                DomNode actualDomRelationshipNode = null;
                foreach (var actualNode in actualNodes)
                {
                    var domRelationship = (IDomRelationship)actualNode;
                    if (domRelationship.Rel != expectedRel)
                    {
                        continue;
                    }

                    actualDomRelationshipNode = actualNode;
                    break;
                }

                Assert.NotNull(actualDomRelationshipNode);

                DomRelationshipAssert.Equal(expectedRel, expectedRelationship, actualDomRelationshipNode);
            }
        }
예제 #6
0
        // INTERNAL CONSTRUCTORS ////////////////////////////////////////////
        #region Constructors
        internal RelationshipsCollectionBuilder(TParentBuilder parentBuilder, IServiceModel serviceModel, IReadOnlyCollection <IContainerNode <DomNodeType> > domContainerNodeCollection, IReadOnlyList <TResource> clrResourceCollection)
        {
            Contract.Requires(parentBuilder != null);
            Contract.Requires(serviceModel != null);
            Contract.Requires(domContainerNodeCollection != null);

            var domReadWriteRelationshipsCollectionCount = domContainerNodeCollection.Count;
            var clrResourceCollectionCount = clrResourceCollection.Count;

            if (clrResourceCollectionCount != domReadWriteRelationshipsCollectionCount)
            {
                var detail = ServerErrorStrings
                             .InternalErrorExceptionDetailCollectionCountMismatch
                             .FormatWith("DOM read-write relationships collection", domReadWriteRelationshipsCollectionCount, "CLR resource collection", clrResourceCollectionCount);
                throw new InternalErrorException(detail);
            }

            this.ParentBuilder = parentBuilder;

            this.ServiceModel = serviceModel;

            var resourceType = serviceModel.GetResourceType <TResource>();

            this.ResourceType = resourceType;

            var domReadWriteRelationshipsCollection = domContainerNodeCollection
                                                      .Select(x => x.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create()))
                                                      .ToList();

            this.DomReadWriteRelationshipsCollection = domReadWriteRelationshipsCollection;

            this.ClrResourceCollection = clrResourceCollection;
        }
예제 #7
0
        // INTERNAL CONSTRUCTORS ////////////////////////////////////////////
        #region Constructors
        internal RelationshipsBuilder(TParentBuilder parentBuilder, IServiceModel serviceModel, IContainerNode <DomNodeType> domContainerNode, Type clrResourceType, object clrResource)
        {
            Contract.Requires(parentBuilder != null);
            Contract.Requires(serviceModel != null);
            Contract.Requires(domContainerNode != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(clrResource != null);

            this.ParentBuilder = parentBuilder;

            this.ServiceModel = serviceModel;

            var resourceType = serviceModel.GetResourceType(clrResourceType);

            this.ResourceType = resourceType;

            var domReadWriteRelationships = domContainerNode.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create());

            this.DomReadWriteRelationships = domReadWriteRelationships;

            this.ClrResource = clrResource;
        }
        private void ResolveResourceRelationship(IDomRelationship domRelationship,
                                                 IHypermediaContext hypermediaContext,
                                                 IHypermediaAssembler hypermediaAssembler,
                                                 IResourcePathContext resourcePathContext,
                                                 Type clrResourceType,
                                                 object clrResource,
                                                 DomReadWriteRelationships domReadWriteRelationships)
        {
            if (domRelationship.IsReadOnly)
            {
                return;
            }

            // Resolve read-write relationship
            var domReadWriteRelationship = (DomReadWriteRelationship)domRelationship;

            // .. Rel
            var apiRelationshipRel = domReadWriteRelationship.Rel;

            // .. Links
            var linkContexts         = new List <ILinkContext>();
            var domRelationshipLinks = (IDomLinks)domReadWriteRelationship.GetNode(DomNodeType.Links);

            if (domRelationshipLinks != null)
            {
                if (domRelationshipLinks.IsReadOnly)
                {
                    // A read-write relationship contains unexpected read-only relationship links.
                    var detail = ServerErrorStrings.DomExceptionDetailReadWriteNodeHasUnexpectedReadOnlyChildNode
                                 .FormatWith(DomNodeType.Relationship, DomNodeType.Links);
                    throw new DomException(detail);
                }

                var domReadWriteRelationshipLinks = (DomReadWriteLinks)domRelationshipLinks;
                foreach (var domLink in domReadWriteRelationshipLinks.Nodes().Cast <IDomLink>())
                {
                    if (domLink.IsReadOnly)
                    {
                        // A read-write relationship contains unexpected read-only relationship link.
                        var detail = ServerErrorStrings.DomExceptionDetailReadWriteNodeHasUnexpectedReadOnlyChildNode
                                     .FormatWith(DomNodeType.Relationship, DomNodeType.Link);
                        throw new DomException(detail);
                    }

                    // Resolve read-write relationship link
                    var domReadWriteLink = (DomReadWriteLink)domLink;
                    var apiLinkRel       = domReadWriteLink.Rel;

                    var apiLinkMeta = default(Meta);
                    var domMeta     = (IDomMeta)domReadWriteLink.GetNode(DomNodeType.Meta);
                    if (domMeta != null)
                    {
                        apiLinkMeta = domMeta.Meta;
                    }

                    var linkContext = new LinkContext(apiLinkRel, apiLinkMeta);
                    linkContexts.Add(linkContext);
                }
            }

            // .. Data
            var resourceType = this.ServiceModel.GetResourceType(clrResourceType);
            var fromApiResourceIdentifier = resourceType.GetApiResourceIdentifier(clrResource);

            var             resourceLinkageKey = new ResourceLinkageKey(fromApiResourceIdentifier, apiRelationshipRel);
            ResourceLinkage resourceLinkage;
            var             hasResourceLinkage = this.DocumentBuilderContext.TryGetResourceLinkage(resourceLinkageKey, out resourceLinkage);

            // .. Meta
            var apiRelationshipMeta = default(Meta);
            var domRelationshipMeta = (IDomMeta)domReadWriteRelationship.GetNode(DomNodeType.Meta);

            if (domRelationshipMeta != null)
            {
                apiRelationshipMeta = domRelationshipMeta.Meta;
            }

            // Create the correct relationship context based on resource linkage (if any).
            RelationshipContext relationshipContext;

            if (hasResourceLinkage)
            {
                var resourceLinkageType = resourceLinkage.Type;
                switch (resourceLinkageType)
                {
                case ResourceLinkageType.ToOneResourceLinkage:
                {
                    var toOneResourceLinkage = resourceLinkage.ToOneResourceLinkage;
                    relationshipContext = new ToOneRelationshipContext(apiRelationshipRel, linkContexts, toOneResourceLinkage, apiRelationshipMeta);
                }
                break;

                case ResourceLinkageType.ToManyResourceLinkage:
                {
                    var toManyResourceLinkage = resourceLinkage.ToManyResourceLinkage;
                    relationshipContext = new ToManyRelationshipContext(apiRelationshipRel, linkContexts, toManyResourceLinkage, apiRelationshipMeta);
                }
                break;

                default:
                {
                    var detail = InfrastructureErrorStrings.InternalErrorExceptionDetailUnknownEnumerationValue
                                 .FormatWith(typeof(ResourceLinkageType).Name, resourceLinkageType);
                    throw new InternalErrorException(detail);
                }
                }
            }
            else
            {
                relationshipContext = new RelationshipContext(apiRelationshipRel, linkContexts, apiRelationshipMeta);
            }

            // Create relationship.
            var apiResourceRelationship = hypermediaAssembler.CreateResourceRelationship(hypermediaContext, resourcePathContext, clrResourceType, clrResource, relationshipContext);

            // Replace the old DOM read-write relationship node with a new DOM read-only relationship created by the framework.
            var domReadOnlyRelationship = DomReadOnlyRelationship.Create(apiRelationshipRel, apiResourceRelationship);

            domReadWriteRelationships.ReplaceNode(domReadWriteRelationship, domReadOnlyRelationship);
        }
        internal void TestDomReadWriteRelationshipsCreate(string name, Relationships expected, DomReadWriteRelationships actual)
        {
            // Arrange

            // Act
            this.Output.WriteLine("Test Name: {0}", name);
            this.Output.WriteLine(String.Empty);
            this.OutputDomTree(actual);

            // Assert
            DomReadWriteRelationshipsAssert.Equal(expected, actual);
        }
예제 #10
0
        // INTERNAL CONSTRUCTORS ////////////////////////////////////////////
        #region Constructors
        internal RelationshipsCollectionBuilder(TParentBuilder parentBuilder, IServiceModel serviceModel, IReadOnlyCollection <IContainerNode <DomNodeType> > domContainerNodeCollection, Type clrResourceType, IReadOnlyList <object> clrResourceCollection)
        {
            Contract.Requires(parentBuilder != null);
            Contract.Requires(serviceModel != null);
            Contract.Requires(domContainerNodeCollection != null);
            Contract.Requires(clrResourceType != null);
            Contract.Requires(clrResourceCollection != null);

            this.ParentBuilder = parentBuilder;

            this.ServiceModel = serviceModel;

            var resourceType = serviceModel.GetResourceType(clrResourceType);

            this.ResourceType = resourceType;

            var domReadWriteRelationshipsCollection = domContainerNodeCollection
                                                      .Select(x => x.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create()))
                                                      .ToList();

            this.DomReadWriteRelationshipsCollection = domReadWriteRelationshipsCollection;

            this.ClrResourceCollection = clrResourceCollection;
        }
예제 #11
0
        // INTERNAL CONSTRUCTORS ////////////////////////////////////////////
        #region Constructors
        internal RelationshipsBuilder(TParentBuilder parentBuilder, IContainerNode <DomNodeType> domContainerNode, TResource clrResource)
        {
            Contract.Requires(parentBuilder != null);
            Contract.Requires(domContainerNode != null);
            Contract.Requires(clrResource != null);

            this.ParentBuilder = parentBuilder;

            var domReadWriteRelationships = domContainerNode.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create());

            this.DomReadWriteRelationships = domReadWriteRelationships;

            this.ClrResource = clrResource;
        }
예제 #12
0
        // PRIVATE METHODS //////////////////////////////////////////////////
        #region Methods
        private void AddDomReadWriteRelationshipIfNeeded(ApiResourceLinkageKey apiResourceLinkageKey)
        {
            // Add DOM read/write relationship node if not already added.
            var fromApiResourceIdentifier = apiResourceLinkageKey.FromResourceIdentifier;
            var fromApiRel = apiResourceLinkageKey.FromRel;

            if (!this.DomReadWriteResourceDictionary.TryGetValue(fromApiResourceIdentifier, out var domResource))
            {
                return;
            }

            var domReadWriteRelationships = (DomReadWriteRelationships)domResource.GetNode(DomNodeType.Relationships);

            // ReSharper disable once ConvertIfStatementToNullCoalescingExpression
            if (domReadWriteRelationships == null)
            {
                // Add DOM read/write relationships node
                domReadWriteRelationships = domResource.GetOrAddNode(DomNodeType.Relationships, () => DomReadWriteRelationships.Create());
            }

            var domReadWriteRelationshipExists = domReadWriteRelationships.Nodes()
                                                 .Cast <IDomRelationship>()
                                                 .Any(x => x.Rel == fromApiRel);

            if (domReadWriteRelationshipExists)
            {
                return;
            }

            // Add DOM read/write relationship node.
            domReadWriteRelationships.AddDomReadWriteRelationship(fromApiRel);
        }