public static Field FieldCreator() {
     var randomNumber = RandomNumber.Next(1, 8);
     switch (randomNumber) {
         case 1:
             return new TextField { Name = "TextField{0}".FormatString(RandomNumber.Next(0, 999)) };
         case 2:
             return new BooleanField { Name = "BooleanField{0}".FormatString(RandomNumber.Next(0, 999)) };
         case 3:
             return new DateTimeField { Name = "DateTimeField{0}".FormatString(RandomNumber.Next(0, 999)) };
         case 4:
             return new NumericField { Name = "NumericField{0}".FormatString(RandomNumber.Next(0, 999)) };
         case 5:
             return new HtmlField { Name = "HtmlField{0}".FormatString(RandomNumber.Next(0, 999)) };
         case 6:
         case 7:
             return new EnumerableField
                    {
                        Name = "EnumerableField{0}".FormatString(RandomNumber.Next(0, 999)),
                        EnumerableOf = FieldCreator()
                    };
         case 8:
             var arbitraryObjectField = new ArbitraryObjectField
                                        {
                                            Name =
                                                "ArbitraryObjectField{0}".FormatString
                                                (RandomNumber.Next(0, 999))
                                        };
             for (int i = 0; i < 3; i++) {
                 arbitraryObjectField.Fields.Add(FieldCreator());
             }
             return arbitraryObjectField;
         default:
             return default(Field);
     }
 }
        public static IEnumerable<object[]> Data() {
            var metaType = new MetaType { Name = "some_meta_type" };

            metaType.Fields.Add(new BooleanField { Name = "Field1" });
            metaType.Fields.Add(new BooleanField { Name = "field1" });

            yield return new object[] { metaType };


            metaType = new MetaType { Name = "some_meta_type" };
            var obj = new ArbitraryObjectField { Name = "obj1" };
            obj.Fields.Add(new BooleanField { Name = "Field1" });
            obj.Fields.Add(new BooleanField { Name = "field1" });
            metaType.Fields.Add(obj);

            yield return new object[] { metaType };

            metaType = new MetaType { Name = "some_meta_type" };
            var obj1 = new ArbitraryObjectField { Name = "obj1" };
            var obj2 = new ArbitraryObjectField { Name = "obj2" };
            obj2.Fields.Add(new BooleanField { Name = "Field1" });
            obj2.Fields.Add(new BooleanField { Name = "field1" });
            obj1.Fields.Add(obj2);
            metaType.Fields.Add(obj1);

            yield return new object[] { metaType };
        }
        public void Should_not_be_able_to_add_duplicate_fields_top_level_or_to_objects_nested_N_levels_deep(int n) {
            using (var server = TestServer.Create<TestStartup>()) {
                // arrange
                var fixture = AutofixtureHelpers.CreateFixture();
                var metaType = fixture.Build<MetaType>().Without(type => type.Id).Create();

                using (var session = Storage.GetAsyncSession()) {
                    session.StoreAsync(metaType).Wait();
                    session.SaveChangesAsync().Wait();
                }

                var i = 0;
                var fields = metaType.Fields;
                while (i < n) {

                    var obj = new ArbitraryObjectField { Name = "obj{0}".FormatString(i) };
                    obj.Fields.Add(new BooleanField { Name = "someField" });
                    fields.Add(obj);
                    fields = obj.Fields;


                    if (i == n - 1) {
                        fields.Add(new BooleanField { Name = "Field1" });
                        fields.Add(new BooleanField { Name = "field1" });
                    }
                    i++;
                }

                // act
                var json = JsonConvert.SerializeObject(metaType, this.JsonSerializerSettings);

                var response =
                    server.CreateRequest("api/metatypes")
                          .And(message => message.Content = new StringContent(json, Encoding.UTF8, "application/json"))
                          .SendAsync("PUT")
                          .Result;

                // verify
                var result = JsonConvert.DeserializeObject<ApiError>(response.Content.ReadAsStringAsync().Result);
                Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
                Assert.Equal(ApiErrorCode.DuplicateFieldName, result.ErrorCode);
            }
        }
        public void Should_not_be_able_to_create_models_with_ArbitraryObject_fields_N_levels_deep_with_an_empty_object_value(int n) {
            using (var server = TestServer.Create<TestStartup>()) {
                // arrange
                var schema = new MetaType { Name = "simple_schema" };
                var i = 0;
                var fields = schema.Fields;
                while (i < n) {
                    var obj = new ArbitraryObjectField { Name = "obj{0}".FormatString(i) };
                    fields.Add(obj);
                    fields = obj.Fields;
                    i++;
                }
                using (var session = Storage.GetAsyncSession()) {
                    session.StoreAsync(schema).Wait();
                    session.SaveChangesAsync().Wait();
                }

                // act
                i = 0;
                var model = new Model { };
                var o = model as Dough;
                while (i < n) {
                    var fieldName = "obj{0}".FormatString(i);
                    o[fieldName] = new Dough { };
                    o = o[fieldName] as Dough;
                    i++;
                }
                var json = JsonConvert.SerializeObject(model, this.JsonConverter);
                var response =
                    server.CreateRequest("api/models/{0}".FormatString(schema.Name))
                          .And(message => message.Content = new StringContent(json, Encoding.UTF8, "application/json"))
                          .PostAsync()
                          .Result;

                // verify
                Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
                var content = response.Content.ReadAsStringAsync().Result;
                var result = JsonConvert.DeserializeObject<ApiError>(content);
                Assert.Equal(ApiErrorCode.SchemaMismatch, result.ErrorCode);
            }
        }