public async Task EvaluateAsync_DoesManipulate_AsExpected(string?key, int?param, bool explicitOnly, bool disallowParameterless, int expected)
        {
            // Arrange
            var condition = new CountRatingCondition(0, 10)
            {
                ExplicitManipulationOnly          = explicitOnly,
                DisallowParamaterlessManipulation = disallowParameterless,
                CacheCurrentValue = false
            };
            var gateway = new RatingGateway();

            gateway.AddCondition(key ?? nameof(CountRatingCondition), condition);

            // Act
            if (key == null)
            {
                await gateway.EvaluateAsync();
            }
            else
            {
                await gateway.EvaluateAsync(new Dictionary <string, object?>()
                {
                    { key, param }
                });
            }

            // Assert
            Assert.Equal(expected, condition.CurrentState);
        }
        public void Evaluate_ResetOnlyWhen_EvaluationSuccess()
        {
            // Arrange
            var ratingViewMock = new Mock <IRatingView>();
            var gateway        = new RatingGateway
            {
                RatingView = ratingViewMock.Object
            };
            var condition1 = new CountRatingCondition(0, 2, ConditionType.Requirement)
            {
                CacheCurrentValue = false
            };
            var condition2 = new CountRatingCondition(0, 1, ConditionType.Requirement)
            {
                CacheCurrentValue            = false,
                ResetOnlyOnEvaluationSuccess = false
            };
            var condition3 = new CountRatingCondition(0, 1, ConditionType.Requirement)
            {
                CacheCurrentValue = false
            };

            gateway.AddCondition("test", condition1);
            gateway.AddCondition("test2", condition2);
            gateway.AddCondition("test3", condition3);

            // Act
            gateway.Evaluate();

            // Assert
            ratingViewMock.Verify(view => view.TryOpenRatingPage(), Times.Never);
            Assert.Equal(1, condition1.CurrentState);
            Assert.Equal(0, condition2.CurrentState);
            Assert.Equal(1, condition3.CurrentState);
        }
        public void Evaluate_OpensRatingPage()
        {
            // Arrange
            var ratingViewMock = new Mock <IRatingView>();
            var gateway        = new RatingGateway
            {
                RatingView = ratingViewMock.Object
            };
            var condition1 = new CountRatingCondition(0, 1)
            {
                CacheCurrentValue = false
            };

            gateway.AddCondition("test", condition1);

            // Act
            gateway.Evaluate();
            gateway.Evaluate("test");
            gateway.Evaluate(new Dictionary <string, object?>()
            {
                { "test", null }
            });

            // Assert
            ratingViewMock.Verify(view => view.TryOpenRatingPage(), Times.Exactly(3));
            ratingViewMock.Verify(view => view.TryOpenRatingPageAsync(), Times.Never);
        }
        public void Evaluate_DoesResetAllMetConditions_ExceptStrictlyForbiddenOnes()
        {
            // Arrange
            var ratingViewMock = new Mock <IRatingView>();
            var gateway        = new RatingGateway
            {
                RatingView = ratingViewMock.Object
            };
            var condition1 = new CountRatingCondition(0, 1, ConditionType.Requirement)
            {
                CacheCurrentValue = false
            };
            var condition2 = new BooleanRatingCondition(ConditionType.Requirement)
            {
                ResetAfterConditionMet = false
            };

            gateway.AddCondition("test", condition1);
            gateway.AddCondition("test2", condition2);

            // Act
            gateway.Evaluate();

            // Assert
            ratingViewMock.Verify(view => view.TryOpenRatingPage(), Times.Once);
            Assert.Equal(0, condition1.CurrentState);
            Assert.True(condition2.CurrentState);
        }
        public void ResetAllConditions_IsSuccessful()
        {
            // Arrange
            var condition1 = new CountRatingCondition(0, 10)
            {
                CacheCurrentValue = false
            };
            var condition2 = new CountRatingCondition(1, 7)
            {
                CacheCurrentValue = false
            };
            var conditions = new Dictionary <string, IRatingCondition>()
            {
                { "Test1", condition1 },
                { "Test2", condition2 }
            };
            var gateway = new RatingGateway();

            gateway.AddCondition(conditions);
            condition1.ManipulateState(10);
            condition2.ManipulateState(7);

            // Act
            gateway.ResetAllConditions();

            // Assert
            Assert.False(condition1.IsConditionMet);
            Assert.False(condition2.IsConditionMet);
        }
        public async Task EvaluateAsync_DoesResetAllMetConditions()
        {
            // Arrange
            var ratingViewMock = new Mock <IRatingView>();
            var gateway        = new RatingGateway
            {
                RatingView = ratingViewMock.Object
            };
            var condition1 = new CountRatingCondition(0, 1, ConditionType.Requirement)
            {
                CacheCurrentValue = false
            };
            var condition2 = new BooleanRatingCondition(ConditionType.Requirement);

            gateway.AddCondition("test", condition1);
            gateway.AddCondition("test2", condition2);

            // Act
            await gateway.EvaluateAsync();

            // Assert
            ratingViewMock.Verify(view => view.TryOpenRatingPage(), Times.Never);
            ratingViewMock.Verify(view => view.TryOpenRatingPageAsync(), Times.Once);
            Assert.Equal(0, condition1.CurrentState);
            Assert.False(condition2.CurrentState);
        }
        public void ManipulateState_Should_BumpCurrentStateByOne()
        {
            // Arrange
            var condition = new CountRatingCondition(0, 10);

            // Act
            condition.ManipulateState();

            // Assert
            Assert.Equal(1, condition.CurrentState);
        }
        public void IsConditionMet_EvaluatesTo_ExpectedResult(int initial, int goal, int?param, bool expected)
        {
            // Arrange
            var condition = new CountRatingCondition(initial, goal);

            // Act
            if (param == null)
            {
                condition.ManipulateState();
            }
            else
            {
                condition.ManipulateState(param);
            }

            // Assert
            Assert.Equal(expected, condition.IsConditionMet);
        }