public void UpdateField( )
        {
            var rq = new EntityMemberRequest( );

            rq.Fields.Add(new EntityRef("description"));

            var        svc    = new EntityInfoService( );
            EntityData entity = svc.GetEntityData(new EntityRef("test", "person"), rq);

            entity.Fields[0].Value.Value = "Hello world";
            svc.UpdateEntity(entity);
        }
        public void UpdateRelationships(string cardinality, string options, string expect)
        {
            var type1 = Create <EntityType>(true);
            var type2 = Create <EntityType>(true);
            var rel   = Create <Relationship>( );

            rel.FromType    = type1;
            rel.ToType      = type2;
            rel.Cardinality = Entity.Get <CardinalityEnum>(new EntityRef("core:" + cardinality));
            rel.Save( );

            var inst1  = Entity.Create(type1.Id);
            var inst2a = Entity.Create(type2.Id);
            var inst2b = Entity.Create(type2.Id);
            var inst3  = Entity.Create(type2.Id);

            SetRel(inst1, inst2a, rel);

            if (options.Contains("rel3"))
            {
                SetRel(inst3, inst2b, rel);
            }

            EntityData data = new EntityData
            {
                Id            = new EntityRef(inst1.Id),
                Relationships = new List <RelationshipData>
                {
                    new RelationshipData
                    {
                        RemoveExisting     = options.Contains("removeExisting"),
                        DeleteExisting     = options.Contains("deleteExisting"),
                        AutoCardinality    = options.Contains("autoCardinality"),
                        RelationshipTypeId = new EntityRef(rel.Id),
                        Instances          = new List <RelationshipInstanceData>
                        {
                            new RelationshipInstanceData {
                                DataState = DataState.Create,
                                Entity    = new EntityData {
                                    Id = new EntityRef(inst2b.Id)
                                }
                            }
                        }
                    }
                }
            };

            // Call service
            var svc = new EntityInfoService( );

            svc.UpdateEntity(data);

            Assert.That(Entity.Exists(inst1.Id), Is.EqualTo(expect.Contains("ent1")), "ent1");
            Assert.That(Entity.Exists(inst2a.Id), Is.EqualTo(expect.Contains("ent2a")), "ent2a");
            Assert.That(Entity.Exists(inst2b.Id), Is.EqualTo(expect.Contains("ent2b")), "ent2b");

            var values = inst1.GetRelationships(rel).Select(r => r.Entity.Id).ToList( );

            Assert.That(values.Contains(inst2a.Id), Is.EqualTo(expect.Contains("rel2a")), "rel2a");
            Assert.That(values.Contains(inst2b.Id), Is.EqualTo(expect.Contains("rel2b")), "rel2b");

            var values2 = inst3.GetRelationships(rel).Select(r => r.Entity.Id).ToList( );

            Assert.That(values2.Contains(inst2b.Id), Is.EqualTo(expect.Contains("rel3")), "rel3");
        }
        public void UpdateFieldOnRelatedInstance( )
        {
            // Define a new entity
            var data = new EntityData
            {
                Fields  = new List <FieldData>( ),
                TypeIds = new EntityRef("test", "person").ToEnumerable().ToList()
            };

            data.Fields.Add(new FieldData
            {
                FieldId = new EntityRef("name"),
                Value   = new TypedValue("Isaac Newton")
            });

            // Define a new related entity
            var data2 = new EntityData
            {
                Fields  = new List <FieldData>( ),
                TypeIds = new EntityRef("test", "employee").ToEnumerable().ToList()
            };

            data2.Fields.Add(new FieldData
            {
                FieldId = new EntityRef("name"),
                Value   = new TypedValue("Isaac Newtons Emmployer")
            });
            data2.DataState = DataState.Create;

            data.Relationships = new List <RelationshipData>
            {
                new RelationshipData
                {
                    RelationshipTypeId = new EntityRef("test", "reportsTo"),
                    IsReverse          = false,
                    Instances          = new List <RelationshipInstanceData>
                    {
                        new RelationshipInstanceData
                        {
                            Entity    = data2,
                            DataState = DataState.Create
                        }
                    },
                }
            };

            // Create it
            var       svc = new EntityInfoService( );
            EntityRef id  = svc.CreateEntity(data);

            // Verify it was created
            Assert.IsTrue(id.Id > 0, "Positive Id");

            // Select the data
            EntityMemberRequest request = EntityRequestHelper.BuildRequest("name, test:reportsTo.name");
            EntityData          result  = svc.GetEntityData(id, request);

            // Verify results
            Assert.AreEqual("Isaac Newton", result.Fields[0].Value.Value);

            EntityData employee           = result.Relationships[0].Instances[0].Entity;
            FieldData  employersNameField = employee.Fields[0];

            Assert.AreEqual("Isaac Newtons Emmployer", employersNameField.Value.Value);

            // Update employees name
            employersNameField.Value.Value = "bob";
            employee.DataState             = DataState.Update;

            svc.UpdateEntity(result);

            // comfirm it changed
            EntityData resultAfterUpdate = svc.GetEntityData(id, request);

            employee           = resultAfterUpdate.Relationships[0].Instances[0].Entity;
            employersNameField = employee.Fields[0];
            Assert.AreEqual("bob", employersNameField.Value.Value);

            // delete the referenced Entity leaving the data state of the top entity unchanged
            employee.DataState = DataState.Delete;

            svc.UpdateEntity(resultAfterUpdate);

            // comfirm it deleted
            EntityData resultAfterDelete = svc.GetEntityData(id, request);

            Assert.AreEqual(0, resultAfterDelete.Relationships[0].Instances.Count, "There should be no manager");

            // clean up
            svc.DeleteEntity(id);
        }
        public void UpdateEntityRemoveExistingFromCascadeDeleted()
        {
            /////////////////////////////////////////////////////////////////////////////////////////
            // Arrange
            /////////////////////////////////////////////////////////////////////////////////////////
            var typeA = Create <EntityType>(true);
            var typeB = Create <EntityType>(true);
            var typeC = Create <EntityType>(true);
            var rel1  = Create <Relationship>();

            rel1.FromType         = typeA;
            rel1.ToType           = typeB;
            rel1.Cardinality_Enum = CardinalityEnum_Enumeration.OneToMany;
            rel1.Save();
            var rel2 = Create <Relationship>();

            rel2.FromType         = typeB;
            rel2.ToType           = typeC;
            rel2.Cardinality_Enum = CardinalityEnum_Enumeration.OneToMany;
            rel2.CascadeDeleteTo  = true;
            rel2.Save();

            var aInstance = Entity.Create(typeA.Id);
            var bInstance = Entity.Create(typeB.Id);
            var cInstance = Entity.Create(typeC.Id);

            SetRel(aInstance, bInstance, rel1);
            SetRel(bInstance, cInstance, rel2);

            aInstance.IsTemporaryId.Should().BeFalse();
            bInstance.IsTemporaryId.Should().BeFalse();
            cInstance.IsTemporaryId.Should().BeFalse();
            Entity.Exists(aInstance.Id).Should().BeTrue();
            Entity.Exists(bInstance.Id).Should().BeTrue();
            Entity.Exists(cInstance.Id).Should().BeTrue();

            var children = bInstance.GetRelationships(rel2);

            children.Should().NotBeNull().And.NotBeEmpty();
            children.Count.Should().Be(1);
            children.Select(c => c.Id).Should().Contain(cInstance.Id);

            var data = new EntityData
            {
                // top level node is the "update"
                Id            = new EntityRef(aInstance.Id),
                DataState     = DataState.Update,
                Relationships = new List <RelationshipData>
                {
                    new RelationshipData
                    {
                        RelationshipTypeId = new EntityRef(rel1.Id),
                        Instances          = new List <RelationshipInstanceData>
                        {
                            new RelationshipInstanceData
                            {
                                Entity = new EntityData
                                {
                                    // this is the node we are deleting and removing from
                                    Id            = new EntityRef(bInstance.Id),
                                    DataState     = DataState.Delete,
                                    Relationships = new List <RelationshipData>
                                    {
                                        new RelationshipData
                                        {
                                            RemoveExisting     = true,
                                            RelationshipTypeId = new EntityRef(rel2.Id),
                                            Instances          = new List <RelationshipInstanceData>()
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            /////////////////////////////////////////////////////////////////////////////////////////
            // Act
            /////////////////////////////////////////////////////////////////////////////////////////
            var    svc        = new EntityInfoService();
            Action callUpdate = () => svc.UpdateEntity(data);

            callUpdate.ShouldNotThrow();

            /////////////////////////////////////////////////////////////////////////////////////////
            // Assert
            /////////////////////////////////////////////////////////////////////////////////////////
            Entity.Exists(aInstance.Id).Should().BeTrue();
            Entity.Exists(bInstance.Id).Should().BeFalse();

            // should not have been cascade deleted if it was removed from the relationship
            Entity.Exists(cInstance.Id).Should().BeTrue();
        }
        public void UpdateEntityDeleteItemFromSecuresToRelationship()
        {
            // this case requires that the entity to be delete ONLY receives its access for read/delete through
            // the relationship with the entity being updated.
            // (I.e. activityPrompts removed from promptForArguments relationship with promptUserActivity)

            /////////////////////////////////////////////////////////////////////////////////////////
            // Arrange
            /////////////////////////////////////////////////////////////////////////////////////////
            var parentType = Create <EntityType>();

            parentType.Inherits.Add(UserResource.UserResource_Type);
            parentType.Save();

            var childType = Create <EntityType>();

            childType.Inherits.Add(UserResource.UserResource_Type);
            childType.Save();

            var rel = Create <Relationship>();

            rel.FromType         = parentType;
            rel.ToType           = childType;
            rel.Cardinality_Enum = CardinalityEnum_Enumeration.OneToMany;
            rel.SecuresTo        = true;
            rel.Save();

            var parentInstance = Entity.Create(parentType.Id);
            var childInstance  = Entity.Create(childType.Id);

            SetRel(parentInstance, childInstance, rel);

            parentInstance.IsTemporaryId.Should().BeFalse();
            childInstance.IsTemporaryId.Should().BeFalse();
            Entity.Exists(parentInstance.Id).Should().BeTrue();
            Entity.Exists(childInstance.Id).Should().BeTrue();

            var user = Create <UserAccount>(true);

            user.Name = "UpdateEntityDeleteItemFromSecuresToRelationship";
            user.Save();
            using (new SetUser(user))
            {
                Action getParentNoPermission = () => Entity.Get(parentInstance.Id);
                getParentNoPermission.ShouldThrow <PlatformSecurityException>().WithMessage("*does not have view access to*");

                Action getChildNoPermission = () => Entity.Get(childInstance.Id);
                getChildNoPermission.ShouldThrow <PlatformSecurityException>().WithMessage("*does not have view access to*");
            }

            // grant access via parent
            var query       = TestQueries.Entities(parentType);
            var queryResult = Factory.QueryRunner.ExecuteQuery(query, new QuerySettings {
                SecureQuery = true
            });

            queryResult.Should().NotBeNull();
            queryResult.DataTable.Rows.Count.Should().Be(1);
            queryResult.DataTable.Rows[0].ItemArray.Should().Contain(parentInstance.Id);

            new AccessRuleFactory().AddAllowByQuery(user.As <Subject>(),
                                                    parentType.As <SecurableEntity>(),
                                                    new[] { Permissions.Read, Permissions.Modify, Permissions.Delete },
                                                    query.ToReport());

            Factory.EntityAccessControlService.ClearCaches();

            using (new SetUser(user))
            {
                IEntity p = null;
                Action  getParentPermission = () => p = Entity.Get(parentInstance.Id);
                getParentPermission.ShouldNotThrow();
                p.Should().NotBeNull();
                p.Id.ShouldBeEquivalentTo(parentInstance.Id);

                IEntity c = null;
                Action  getChildPermission = () => c = Entity.Get(childInstance.Id);
                getChildPermission.ShouldNotThrow();
                c.Should().NotBeNull();
                c.Id.ShouldBeEquivalentTo(childInstance.Id);
            }

            var data = new EntityData
            {
                Id            = new EntityRef(parentInstance.Id),
                Relationships = new List <RelationshipData>
                {
                    new RelationshipData
                    {
                        RelationshipTypeId = new EntityRef(rel.Id),
                        Instances          = new List <RelationshipInstanceData>
                        {
                            new RelationshipInstanceData {
                                Entity = new EntityData {
                                    Id = new EntityRef(childInstance.Id), DataState = DataState.Delete
                                }
                            }
                        }
                    }
                }
            };

            /////////////////////////////////////////////////////////////////////////////////////////
            // Act
            /////////////////////////////////////////////////////////////////////////////////////////
            using (new SetUser(user))
            {
                var    svc        = new EntityInfoService();
                Action callUpdate = () => svc.UpdateEntity(data);
                callUpdate.ShouldNotThrow();
            }

            /////////////////////////////////////////////////////////////////////////////////////////
            // Assert
            /////////////////////////////////////////////////////////////////////////////////////////
            Entity.Exists(parentInstance.Id).Should().BeTrue();
            Entity.Exists(childInstance.Id).Should().BeFalse();
        }
        /// <summary>
        ///     Handles post data.
        /// </summary>
        /// <param name="entityData">The entity data.</param>
        /// <param name="returnMap">if set to <c>true</c> [return map].</param>
        /// <returns></returns>
        private HttpResponseMessage HandlePost(JsonEntityQueryResult entityData, bool returnMap)
        {
            Stopwatch sw = Stopwatch.StartNew( );
            long      t1;

            // resolve all entity ids above our 'known id hi watermark' that actually do exist
            entityData.ResolveIds( );

            long id = entityData.Ids.FirstOrDefault( );
            IDictionary <long, IEntity> map = null;

            if (id >= JsonEntityQueryResult.BaseNewId)
            {
                // create
                EventLog.Application.WriteTrace("Creating entity " + id);
                EntityData newEntityData = entityData.GetEntityData(id);

                t1 = sw.ElapsedMilliseconds;

                DatabaseContext.RunWithRetry(() =>
                {
                    using (DatabaseContext context = DatabaseContext.GetContext(true))
                    {
#pragma warning disable 618
                        var svc = new EntityInfoService();
#pragma warning restore 618

                        map = svc.CreateEntityGetMap(newEntityData);

                        IEntity entity = map[newEntityData.Id.Id];
                        id             = entity == null ? -1 : entity.Id;

                        context.CommitTransaction();
                    }
                });


                EventLog.Application.WriteTrace("EntityPost create took {0} msec ({1} to de-json)",
                                                sw.ElapsedMilliseconds, t1);
            }
            else
            {
                map = new Dictionary <long, IEntity>( );

                EventLog.Application.WriteTrace("Updating entity " + id);
                EntityData newEntityData = entityData.GetEntityData(id);

                t1 = sw.ElapsedMilliseconds;


                DatabaseContext.RunWithRetry(() =>
                {
                    using (DatabaseContext context = DatabaseContext.GetContext(true))
                    {
#pragma warning disable 618
                        var svc = new EntityInfoService();
#pragma warning restore 618
                        svc.UpdateEntity(newEntityData);

                        context.CommitTransaction();
                    }
                });

                EventLog.Application.WriteTrace("EntityPost update took {0} msec ({1} to de-json)",
                                                sw.ElapsedMilliseconds, t1);
            }


            HttpResponseMessage httpResponseMessage;

            if (returnMap)
            {
                /////
                // Create a custom response message so the infrastructure framework doesn't serialize it twice.
                /////
                httpResponseMessage = new HttpResponseMessage
                {
                    Content = new StringContent(DictionaryToJson(map))
                };

                httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
            }
            else
            {
                httpResponseMessage = new HttpResponseMessage <long>(id);
            }

            return(httpResponseMessage);
        }