Exemplo n.º 1
0
        public async Task BuildFullDynamicDto_HasNoSideEffect_Test()
        {
            var entityConfigCacheMock = new Mock <IEntityConfigCache>();

            entityConfigCacheMock.Setup(x => x.GetEntityPropertiesAsync(It.IsAny <Type>()))
            .Returns(() => {
                var result = new EntityPropertyDtoList();
                var r      = result as List <EntityPropertyDto>;
                return(Task.FromResult(r));
            });

            var entityConfigStore = LocalIocManager.Resolve <IEntityConfigurationStore>();
            var cacheManager      = LocalIocManager.Resolve <ICacheManager>();
            var builder           = new DynamicDtoTypeBuilder(entityConfigCacheMock.Object, entityConfigStore, cacheManager);

            var baseDtoType = typeof(DynamicDto <Person, Guid>);

            var proxyType1 = await builder.BuildDtoFullProxyTypeAsync(baseDtoType, new DynamicDtoTypeBuildingContext()
            {
                ModelType             = baseDtoType,
                AddFormFieldsProperty = true,
            });

            var proxyType2 = await builder.BuildDtoFullProxyTypeAsync(baseDtoType, new DynamicDtoTypeBuildingContext()
            {
                ModelType             = baseDtoType,
                AddFormFieldsProperty = false,
            });

            proxyType1.GetProperties().ShouldContain(p => p.Name == nameof(IHasFormFieldsList._formFields));
            proxyType2.GetProperties().ShouldNotContain(p => p.Name == nameof(IHasFormFieldsList._formFields), $"Check internal cache in the '{nameof(DynamicDtoTypeBuilder)}'. Looks like property `{nameof(IHasFormFieldsList._formFields)}` exists in the result type because of caching");
        }
Exemplo n.º 2
0
        public async Task BuildDynamicDto_WidthDtoReferences_Test()
        {
            var entityConfigCacheMock = new Mock <IEntityConfigCache>();

            const string area1PropName = nameof(Person.AreaLevel1);

            entityConfigCacheMock.Setup(x => x.GetEntityPropertiesAsync(It.IsAny <Type>()))
            .Returns(() => {
                var result = new EntityPropertyDtoList();
                result.Add(new EntityPropertyDto
                {
                    Name       = area1PropName,
                    DataType   = DataTypes.EntityReference,
                    EntityType = "Shesha.Core.Area",
                });

                var r = result as List <EntityPropertyDto>;
                return(Task.FromResult(r));
            });

            var entityConfigStore = LocalIocManager.Resolve <IEntityConfigurationStore>();
            var cacheManager      = LocalIocManager.Resolve <ICacheManager>();
            var builder           = new DynamicDtoTypeBuilder(entityConfigCacheMock.Object, entityConfigStore, cacheManager);

            var baseDtoType = typeof(DynamicDto <Person, Guid>);

            var context = new DynamicDtoTypeBuildingContext()
            {
                ModelType = baseDtoType,
                UseDtoForEntityReferences = true,
                // AddFormFieldsProperty = false // note: false is a default value for AddFormFieldsProperty. Leave it blank to test default value
            };
            var proxyType = await builder.BuildDtoFullProxyTypeAsync(baseDtoType, context);

            proxyType.Assembly.IsDynamic.ShouldBeTrue();

            var properties = proxyType.GetProperties();

            properties.ShouldContain(p => p.Name == area1PropName);
            proxyType.ShouldNotBeAssignableTo(typeof(IHasFormFieldsList));

            var area1Prop = properties.FirstOrDefault(p => p.Name == area1PropName);

            area1Prop.ShouldNotBeNull($"{area1PropName} property is missing in the created DTO");

            var area1IsDto = area1Prop.PropertyType == typeof(EntityWithDisplayNameDto <Guid>);

            area1IsDto.ShouldBeTrue($"{area1PropName} is not mapped as '{nameof(EntityWithDisplayNameDto<Guid>)}'");
        }
Exemplo n.º 3
0
        public async Task BuildFullDynamicDto_Test()
        {
            var entityConfigCacheMock = new Mock <IEntityConfigCache>();

            entityConfigCacheMock.Setup(x => x.GetEntityPropertiesAsync(It.IsAny <Type>()))
            .Returns(() => {
                var result = new EntityPropertyDtoList();
                result.AddString("Name", "Name...");
                result.AddString("Description", "Description...");


                var r = result as List <EntityPropertyDto>;
                return(Task.FromResult(r));
            });

            var entityConfigStore = LocalIocManager.Resolve <IEntityConfigurationStore>();
            var cacheManager      = LocalIocManager.Resolve <ICacheManager>();
            var builder           = new DynamicDtoTypeBuilder(entityConfigCacheMock.Object, entityConfigStore, cacheManager);

            var baseDtoType = typeof(DynamicDto <Person, Guid>);

            var context = new DynamicDtoTypeBuildingContext()
            {
                ModelType             = baseDtoType,
                AddFormFieldsProperty = true,
            };
            var proxyType = await builder.BuildDtoFullProxyTypeAsync(baseDtoType, context);

            var properties = proxyType.GetProperties();

            properties.ShouldContain(p => p.Name == "Name");
            properties.ShouldContain(p => p.Name == "Description");
            properties.ShouldContain(p => p.Name == nameof(IHasFormFieldsList._formFields));

            proxyType.ShouldNotBeAssignableTo(typeof(IHasFormFieldsList));
        }
Exemplo n.º 4
0
        public async Task BuildDynamicDto_Test()
        {
            var entityConfigCacheMock = new Mock <IEntityConfigCache>();

            const string supervisorPropName          = "Supervisor";
            const string supervisorFirstNamePropName = "FirstName";
            const string supervisorLastNamePropName  = "LastName";

            entityConfigCacheMock.Setup(x => x.GetEntityPropertiesAsync(It.IsAny <Type>()))
            .Returns(() => {
                var result = new EntityPropertyDtoList();
                result.AddString("Name", "Name...");
                result.AddString("Description", "Description...");

                var nested = new EntityPropertyDto {
                    Name       = supervisorPropName,
                    DataType   = DataTypes.Object,
                    Properties = new List <EntityPropertyDto>(),
                };
                nested.Properties.Add(new EntityPropertyDto {
                    Name = supervisorFirstNamePropName, DataType = DataTypes.String
                });
                nested.Properties.Add(new EntityPropertyDto {
                    Name = supervisorLastNamePropName, DataType = DataTypes.String
                });

                result.Add(nested);


                var r = result as List <EntityPropertyDto>;
                return(Task.FromResult(r));
            });

            var entityConfigStore = LocalIocManager.Resolve <IEntityConfigurationStore>();
            var cacheManager      = LocalIocManager.Resolve <ICacheManager>();
            var builder           = new DynamicDtoTypeBuilder(entityConfigCacheMock.Object, entityConfigStore, cacheManager);

            var baseDtoType = typeof(DynamicDto <Person, Guid>);

            var context = new DynamicDtoTypeBuildingContext()
            {
                ModelType = baseDtoType,
                // AddFormFieldsProperty = false // note: false is a default value for AddFormFieldsProperty. Leave it blank to test default value
            };
            var proxyType = await builder.BuildDtoFullProxyTypeAsync(baseDtoType, context);

            proxyType.Assembly.IsDynamic.ShouldBeTrue();

            var properties = proxyType.GetProperties();

            properties.ShouldContain(p => p.Name == "Name");
            properties.ShouldContain(p => p.Name == "Description");
            properties.ShouldNotContain(p => p.Name == nameof(IHasFormFieldsList._formFields));
            proxyType.ShouldNotBeAssignableTo(typeof(IHasFormFieldsList));

            var supervisorProp = properties.FirstOrDefault(p => p.Name == supervisorPropName);

            supervisorProp.ShouldNotBeNull($"{supervisorPropName} property is missing in the created DTO");

            // nested object should be dynamic
            supervisorProp.PropertyType.Assembly.IsDynamic.ShouldBeTrue();
            typeof(IDynamicNestedObject).IsAssignableFrom(supervisorProp.PropertyType).ShouldBeTrue($"Dynamic nested object must implement {nameof(IDynamicNestedObject)}");

            var nestedProperties = supervisorProp.PropertyType.GetProperties();

            nestedProperties.ShouldContain(p => p.Name == supervisorFirstNamePropName);
            nestedProperties.ShouldContain(p => p.Name == supervisorLastNamePropName);
        }
        public async Task SaveLoad_Test()
        {
            LoginAsHostAdmin();

            // test data
            var props = new Dictionary <EntityPropertyDto, object>
            {
                { new EntityPropertyDto
                  {
                      Name = "UnitTestDynamicString", DataType = DataTypes.String, Source = MetadataSourceType.UserDefined
                  }, "testString" },
                { new EntityPropertyDto
                  {
                      Name = "UnitTestDynamicDate", DataType = DataTypes.Date, Source = MetadataSourceType.UserDefined
                  }, DateTime.Today },
                { new EntityPropertyDto
                  {
                      Name = "UnitTestDynamicDateTime", DataType = DataTypes.DateTime, Source = MetadataSourceType.UserDefined
                  }, DateTime.Now },
                { new EntityPropertyDto
                  {
                      Name = "UnitTestDynamicBoolean", DataType = DataTypes.Boolean, Source = MetadataSourceType.UserDefined
                  }, true },
                { new EntityPropertyDto
                  {
                      Name = "UnitTestDynamicNumber", DataType = DataTypes.Number, Source = MetadataSourceType.UserDefined
                  }, (decimal)123.45 },
                {
                    new EntityPropertyDto
                    {
                        Name       = "UnitTestDynamicObject", DataType = DataTypes.Object, Source = MetadataSourceType.UserDefined,
                        Properties = new List <EntityPropertyDto>()
                        {
                            new EntityPropertyDto {
                                Name = "UnitTestObjectProperty1", DataType = DataTypes.String, Source = MetadataSourceType.UserDefined
                            },
                            new EntityPropertyDto {
                                Name = "UnitTestObjectProperty2", DataType = DataTypes.String, Source = MetadataSourceType.UserDefined
                            }
                        }
                    },
                    new { UnitTestObjectProperty1 = "testObjectProperty1", UnitTestObjectProperty2 = "testObjectProperty2" }
                }
            };

            // configure DTO
            var entityConfigCacheMock = new Mock <IEntityConfigCache>();

            entityConfigCacheMock.Setup(x => x.GetEntityPropertiesAsync(It.IsAny <Type>()))
            .Returns(() =>
            {
                var result = new List <EntityPropertyDto>();
                foreach (var prop in props)
                {
                    result.Add(prop.Key);
                }
                return(Task.FromResult(result));
            });

            var entityConfigStore = LocalIocManager.Resolve <IEntityConfigurationStore>();
            var cacheManager      = LocalIocManager.Resolve <ICacheManager>();
            var builder           = new DynamicDtoTypeBuilder(entityConfigCacheMock.Object, entityConfigStore, cacheManager);
            var baseDtoType       = typeof(DynamicDto <Person, Guid>);
            var context           = new DynamicDtoTypeBuildingContext()
            {
                ModelType = baseDtoType
            };
            var dtoType = await builder.BuildDtoFullProxyTypeAsync(baseDtoType, context);

            var dto = Activator.CreateInstance(dtoType) as DynamicDto <Person, Guid>;

            var properties = dto?.GetType().GetProperties();

            var serializationManager = Resolve <ISerializationManager>();

            // Update DTO properties values with test data
            foreach (var prop in props)
            {
                var p   = properties?.FirstOrDefault(x => prop.Key.Name.ToLower() == x.Name.ToLower());
                var val = prop.Value;
                if (prop.Key.DataType == DataTypes.Object)
                {
                    val = serializationManager.DeserializeProperty(p?.PropertyType, serializationManager.SerializeProperty(prop.Key, val));
                }
                p?.SetValue(dto, val);
            }

            using (var uow = _unitOfWorkManager.Begin())
            {
                var nhuow   = uow as NhUnitOfWork;
                var session = nhuow?.GetSession();

                // Create temporary Entity Properties configs
                var entityConfigRepo = Resolve <IRepository <EntityConfig, Guid> >();
                var entityPropRepo   = Resolve <IRepository <EntityProperty, Guid> >();
                var config           = entityConfigRepo.GetAll().FirstOrDefault(x =>
                                                                                x.TypeShortAlias == typeof(Person).GetEntityConfiguration().TypeShortAlias);
                foreach (var prop in props)
                {
                    var propConf = new EntityProperty()
                    {
                        EntityConfig = config,
                        Name         = prop.Key.Name,
                        DataType     = prop.Key.DataType,
                        Source       = MetadataSourceType.UserDefined
                    };
                    prop.Key.Id = entityPropRepo.Insert(propConf).Id;
                    foreach (var childProp in prop.Key.Properties)
                    {
                        var childPropConf = new EntityProperty()
                        {
                            ParentProperty = propConf,
                            EntityConfig   = config,
                            Name           = prop.Key.Name,
                            DataType       = prop.Key.DataType,
                            Source         = MetadataSourceType.UserDefined
                        };
                        childProp.Id = entityPropRepo.Insert(childPropConf).Id;
                    }
                }

                session?.Flush();

                try
                {
                    var personRepo             = Resolve <IRepository <Person, Guid> >();
                    var dynamicPropertyManager = new DynamicPropertyManager(
                        Resolve <IRepository <EntityProperty, Guid> >(),
                        Resolve <IRepository <EntityPropertyValue, Guid> >(),
                        Resolve <IEntityConfigurationStore>(),
                        Resolve <IDynamicRepository>()
                        )
                    {
                        DtoTypeBuilder = builder, SerializationManager = serializationManager
                    };

                    // Create temporary entity
                    var entity = new Person();
                    var id     = personRepo.Insert(entity).Id;
                    try
                    {
                        // Save dynamic properties to DB
                        await dynamicPropertyManager.MapDtoToEntityAsync <DynamicDto <Person, Guid>, Person, Guid>(dto,
                                                                                                                   entity);

                        session?.Flush();

                        session?.Clear();

                        // Get entity from DB
                        var newEntity = personRepo.Get(id);

                        // Create new DTO and map values from entity to DTO
                        var newDto = Activator.CreateInstance(dtoType) as DynamicDto <Person, Guid>;
                        await dynamicPropertyManager.MapEntityToDtoAsync <DynamicDto <Person, Guid>, Person, Guid>(newEntity,
                                                                                                                   newDto);

                        // Check values. Values from the DB should be the same as from the test list
                        var newProperties = newDto?.GetType().GetProperties();
                        foreach (var prop in props)
                        {
                            var p        = newProperties?.FirstOrDefault(x => prop.Key.Name.ToLower() == x.Name.ToLower());
                            var dtoValue = p?.GetValue(newDto);
                            if (prop.Key.DataType == DataTypes.Object)
                            {
                                var childProperties = dtoValue.GetType().GetProperties();
                                foreach (var childProp in prop.Key.Properties)
                                {
                                    var childP        = childProperties.FirstOrDefault(x => childProp.Name.ToLower() == x.Name.ToLower());
                                    var dtoChildValue = childP.GetValue(dtoValue);
                                    dtoChildValue.ShouldBe(prop.Value.GetType().GetProperty(childProp.Name).GetValue(prop.Value));
                                }
                            }
                            else
                            {
                                dtoValue.ShouldBe(prop.Value);
                            }
                        }
                    }
                    finally
                    {
                        // delete temporary entity
                        session.CreateSQLQuery($"delete from Core_Persons where id = '{id}'").ExecuteUpdate();
                    }
                }
                finally
                {
                    // delete temporary values and properties configs
                    foreach (var prop in props)
                    {
                        session.CreateSQLQuery($"delete from Frwk_EntityPropertyValues where EntityPropertyId = '{prop.Key.Id}'").ExecuteUpdate();
                        if (prop.Key.DataType == DataTypes.Object)
                        {
                            foreach (var childProp in prop.Key.Properties)
                            {
                                session.CreateSQLQuery($"delete from Frwk_EntityProperties where Id = '{childProp.Id}'").ExecuteUpdate();
                            }
                        }
                        session.CreateSQLQuery($"delete from Frwk_EntityProperties where Id = '{prop.Key.Id}'").ExecuteUpdate();
                    }
                }
            }
        }