public void HttpFeatureToggleClient_should_ignore_invalid_responses()
        {
            // Arrange
            var httpClientDouble = new HttpClientDouble();

            httpClientDouble.Setup_GetString(ValidJsonDocument);
            var client = new HttpFeatureToggleClient(httpClientDouble, "url");

            client.UpdateAsync().Wait();

            Assert.AreEqual("Treatment2A", client.GetTreatmentAsync("Feature2", "H", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "Z", "default").Result);
            Assert.AreEqual("Disabled", client.GetTreatmentAsync("Feature3", "M", "default").Result);

            httpClientDouble.Setup_GetString("INVALID CONTENT");

            // Act
            try
            {
                client.UpdateAsync().Wait();
            }
            catch
            {
                // Ignoring exception, UpdatePeriodically ignore them
            }

            // Assert
            Assert.AreEqual("Treatment2A", client.GetTreatmentAsync("Feature2", "H", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "Z", "default").Result);
            Assert.AreEqual("Disabled", client.GetTreatmentAsync("Feature3", "M", "default").Result);
        }
        public void AccessorBuilding_general_test()
        {
            // Arrange
            var httpClientDouble = new HttpClientDouble();

            httpClientDouble.Setup_GetString(ValidJsonDocument);

            var client = new HttpFeatureToggleClient(httpClientDouble, "url");

            var booleanAccessor = client
                                  .CreateFeature <bool>("BooleanFeature")
                                  .AddBehavior("Disabled", false)
                                  .AddBehavior("Enabled", true)
                                  .SetDefaultTreatment("Disabled")
                                  .ForceTreatmentIfNotNull(null)
                                  .Build();

            var forcedBooleanAccessor = client
                                        .CreateFeature <bool>("BooleanFeature")
                                        .AddBehavior("Disabled", false)
                                        .AddBehavior("Enabled", true)
                                        .SetDefaultTreatment("Disabled")
                                        .ForceTreatmentIfNotNull("Enabled")
                                        .Build();

            var dateFormatAccessor = client
                                     .CreateFeature <DateTime, string>("DateBehavior")
                                     .AddBehavior("ISO", x => x.ToString("yyyy-MM-dd"))
                                     .AddBehavior("English", x => x.ToString("MM/dd/yyyy"))
                                     .AddBehavior("Spanish", x => x.ToString("dd/MM/yyyy"))
                                     .SetDefaultTreatment("ISO")
                                     .Build();

            // Act
            client.UpdateAsync().Wait();

            // Assert
            Assert.AreEqual(true, booleanAccessor.Get("N"));
            Assert.AreEqual(true, booleanAccessor.Get("O"));
            Assert.AreEqual(false, booleanAccessor.Get("P"));
            Assert.AreEqual(false, booleanAccessor.Get("Q"));
            Assert.AreEqual(false, booleanAccessor.Get("NotExistentDifferentiator"));

            Assert.AreEqual(true, forcedBooleanAccessor.Get("N"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("O"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("P"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("Q"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("NotExistentDifferentiator"));

            var date = new DateTime(2018, 12, 20);

            Assert.AreEqual("20/12/2018", dateFormatAccessor.Get("Mauro", date));
            Assert.AreEqual("12/20/2018", dateFormatAccessor.Get("Cristian", date));
            Assert.AreEqual("2018-12-20", dateFormatAccessor.Get("Andres", date));
            Assert.AreEqual("2018-12-20", dateFormatAccessor.Get("NotExistentDifferentiator", date));
        }
        public void HttpFeatureToggleClient_should_update_rules_after_update()
        {
            // Arrange
            var httpClientDouble = new HttpClientDouble();

            httpClientDouble.Setup_GetString(ValidJsonDocument);

            var client = new HttpFeatureToggleClient(httpClientDouble, "url");

            // Assert
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "H", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "Z", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature3", "M", "default").Result);

            // Act
            client.UpdateAsync().Wait();

            // Assert
            Assert.AreEqual("Treatment2A", client.GetTreatmentAsync("Feature2", "H", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "Z", "default").Result);
            Assert.AreEqual("Disabled", client.GetTreatmentAsync("Feature3", "M", "default").Result);

            // Arrange
            httpClientDouble.Setup_GetString(AnotherValidJsonDocument);

            // Act
            client.UpdateAsync().Wait();

            // Assert
            Assert.AreEqual("Treatment2B", client.GetTreatmentAsync("Feature2", "Z", "default").Result);

            // Arrange
            httpClientDouble.Setup_GetString(EmptyValidJsonDocument);

            // Act
            client.UpdateAsync().Wait();

            // Assert
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "H", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature2", "Z", "default").Result);
            Assert.AreEqual("default", client.GetTreatmentAsync("Feature3", "M", "default").Result);
        }
        public void AccessorBuilding_should_require_DefaultTreatment()
        {
            // Arrange
            var httpClientDouble = new HttpClientDouble();
            var client           = new HttpFeatureToggleClient(httpClientDouble, "url");

            try
            {
                var booleanAccessor = client
                                      .CreateFeature <bool>("BooleanFeature")
                                      .AddBehavior("Disabled", false)
                                      .AddBehavior("Enabled", true)
                                      .Build();
                Assert.Fail("Expected exception not thrown");
            }
            catch (Exception e)
            {
                Assert.IsInstanceOf(typeof(InvalidOperationException), e);
                Assert.AreEqual("Cannot build a feature without default treatment defined.", e.Message);
            }
        }
        public void Accessors_general_test()
        {
            // Arrange
            var httpClientDouble = new HttpClientDouble();

            httpClientDouble.Setup_GetString(ValidJsonDocument);

            var client                = new HttpFeatureToggleClient(httpClientDouble, "url");
            var booleanAccessor       = new BooleanFeatureAccessorDemo(client);
            var forcedBooleanAccessor = new ForcedBooleanFeatureAccessorDemo(client, "Enabled");
            var dateFormatAccessor    = new DateBehaviorAccessorDemo(client);

            // Act
            client.UpdateAsync().Wait();

            // Assert
            Assert.AreEqual(true, booleanAccessor.Get("N"));
            Assert.AreEqual(true, booleanAccessor.Get("O"));
            Assert.AreEqual(false, booleanAccessor.Get("P"));
            Assert.AreEqual(false, booleanAccessor.Get("Q"));
            Assert.AreEqual(false, booleanAccessor.Get("NotExistentDifferentiator"));

            Assert.AreEqual(true, forcedBooleanAccessor.Get("N"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("O"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("P"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("Q"));
            Assert.AreEqual(true, forcedBooleanAccessor.Get("NotExistentDifferentiator"));

            var mauroFormatter    = dateFormatAccessor.Get("Mauro");
            var cristianFormatter = dateFormatAccessor.Get("Cristian");
            var andresFormatter   = dateFormatAccessor.Get("Andres");
            var defaultFormatter  = dateFormatAccessor.Get("NotExistentDifferentiator");

            var date = new DateTime(2018, 12, 20);

            Assert.AreEqual("20/12/2018", mauroFormatter(date));
            Assert.AreEqual("12/20/2018", cristianFormatter(date));
            Assert.AreEqual("2018-12-20", andresFormatter(date));
            Assert.AreEqual("2018-12-20", defaultFormatter(date));
        }
        public void AccessorBuilding_should_not_accept_unexistent_ForceTreatment()
        {
            // Arrange
            var httpClientDouble = new HttpClientDouble();
            var client           = new HttpFeatureToggleClient(httpClientDouble, "url");

            try
            {
                var booleanAccessor = client
                                      .CreateFeature <bool>("BooleanFeature")
                                      .AddBehavior("Disabled", false)
                                      .AddBehavior("Enabled", true)
                                      .SetDefaultTreatment("Disabled")
                                      .ForceTreatmentIfNotNull("ANOTHER")
                                      .Build();
                Assert.Fail("Expected exception not thrown");
            }
            catch (Exception e)
            {
                Assert.IsInstanceOf(typeof(InvalidOperationException), e);
                Assert.AreEqual("Forced treatment does not match a defined treatment.", e.Message);
            }
        }