public void WithShouldSetWithProperty()
        {
            // arrange
            var containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);

            containerMock.Setup(c => c.Update(It.IsAny <IHateoasRegistration>()));
            var registration = new HateoasRegistration <TestModel>(null, null, containerMock.Object);
            var builder      = new ExpressionBuilder <TestModel>(registration);

            var fluentResult = builder
                               .Get <TestModelController>()
                               .When <ITestModelProvider>((provider, testModel) => provider.HasNextId(testModel));

            containerMock.ResetCalls();

            // act
            Expression <Func <ITestModelProvider, TestModel, object> > getNextExpression = (provider, testModel) => provider.GetNextId(testModel);

            fluentResult.IdFrom <ITestModelProvider>(getNextExpression);
            var expression = builder.GetExpression();

            // assert
            Assert.IsNotNull(expression);
            Assert.AreEqual(getNextExpression, expression.IdFromExpression);
            containerMock.Verify(c => c.Update(It.IsAny <IHateoasRegistration>()), Times.Once);
        }
        public void WithCommandUsingFactoryExpressionShouldSaveCommandTypeAndCommandExpression()
        {
            // arrange
            var containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);

            containerMock.Setup(c => c.Update(It.IsAny <IHateoasRegistration>()));
            var registration = new HateoasRegistration <TestModel>(null, null, containerMock.Object);

            var fluentResult =
                new ExpressionBuilder <TestModel>(registration)
                .Post <TestModelController>();

            containerMock.ResetCalls();

            // act
            Expression <Func <PostCommandFactory, object> > commandFactory = factory => factory.Create();

            fluentResult.WithCommand <PostCommandFactory>(commandFactory);
            var expression = fluentResult.GetExpression();

            // assert
            Assert.IsNotNull(expression);

            Assert.IsNull(expression.Command);
            Assert.IsNotNull(expression.CommandFactory);
            Assert.AreEqual(commandFactory, expression.CommandFactory);
            containerMock.Verify(c => c.Update(It.IsAny <IHateoasRegistration>()), Times.Once);
        }
        public void AsTemplateWithParametersShouldSetTemplateProperty()
        {
            // arrange
            var containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);

            containerMock.Setup(c => c.Update(It.IsAny <IHateoasRegistration>()));
            var registration = new HateoasRegistration <TestModel>(null, null, containerMock.Object);
            var builder      = new ExpressionBuilder <TestModel>(registration);

            var fluentResult = builder.Get <TestModelController>();

            containerMock.ResetCalls();

            // act
            Expression <Func <TestModel, object> > idExpression   = m => m.Id;
            Expression <Func <TestModel, object> > nameExpression = m => m.Name;

            fluentResult.AsTemplate(idExpression, nameExpression);
            var expression = builder.GetExpression();

            // assert
            Assert.IsNotNull(expression);
            Assert.IsTrue(expression.Template);
            var parameters = expression.TemplateParameters.ToList();

            Assert.AreEqual(2, parameters.Count);
            Assert.AreEqual(idExpression, parameters[0]);
            Assert.AreEqual(nameExpression, parameters[1]);
            containerMock.Verify(c => c.Update(It.IsAny <IHateoasRegistration>()), Times.Once);
        }
        public void ConstructorWithRelationParameterShouldSetCorrectProperties()
        {
            // arrange
            const string relation = "relation";

            // act
            var registration = new HateoasRegistration <TestModel>(relation, null);

            // assert
            Assert.AreEqual(relation, registration.Relation);
            Assert.IsNull(registration.ArgumentDefinitions);
            Assert.IsFalse(registration.IsCollection);
        }
        public void ConstructorWithRelationIdSpecificationAndCollectionFlagParametersShouldSetCorrectProperties()
        {
            // arrange
            const string relation = "relation";
            Expression <Func <TestModel, object> > identityDefinition = m => m.Id;

            // act
            var registration = new HateoasRegistration <TestModel>(relation, new [] { identityDefinition }, null, true);

            // assert
            Assert.AreEqual(relation, registration.Relation);
            Assert.AreEqual(identityDefinition, registration.ArgumentDefinitions[0]);
            Assert.IsTrue(registration.IsCollection);
        }
        public void IHateoasRegistrationExpressionShouldSetExpressionProperty()
        {
            // arrange
            var registration = new HateoasRegistration <TestModel>(null);

            var expressionMock = new Mock <IHateoasExpression <TestModel> >(MockBehavior.Strict);
            var registrationAsIHateoasRegistration = (IHateoasRegistration)registration;

            registrationAsIHateoasRegistration.Expression = expressionMock.Object;
            var assignedEpression = registrationAsIHateoasRegistration.Expression;

            // assert
            assignedEpression.Should().NotBeNull().And.Be(expressionMock.Object);
            registration.Expression.Should().NotBeNull().And.Be(expressionMock.Object);
        }
        public void ConstructorShouldSaveRegistration()
        {
            // arrange
            var          containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);
            const string relation      = "relation";
            Expression <Func <TestModel, object> > identityDefinition = m => m.Id;
            var registration = new HateoasRegistration <TestModel>(relation, new [] { identityDefinition }, containerMock.Object);

            // act
            var builder    = new ExpressionBuilder <TestModel>(registration);
            var expression = builder.GetExpression();

            // assert
            Assert.IsNotNull(expression);

            Assert.AreEqual(relation, expression.Relation);
            Assert.AreEqual(identityDefinition, expression.ArgumentDefinitions[0]);
            Assert.IsFalse(expression.IsCollection);
        }
        public void GetShouldSaveControllerAndSetHttpMethodGet()
        {
            // arrange
            var containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);

            containerMock.Setup(c => c.Update(It.IsAny <IHateoasRegistration>()));
            var registration = new HateoasRegistration <TestModel>(null, null, containerMock.Object);
            var builder      = new ExpressionBuilder <TestModel>(registration);

            // act
            builder.Get <TestModelController>();
            var expression = builder.GetExpression();

            // assert
            Assert.IsNotNull(expression);

            Assert.AreEqual(typeof(TestModelController), expression.Controller);
            Assert.AreEqual(HttpMethod.Get, expression.HttpMethod);
            Assert.IsNull(expression.Action);
            containerMock.Verify(c => c.Update(It.IsAny <IHateoasRegistration>()), Times.Once);
        }
        public void AsCollectionShouldSetCollectionProperty()
        {
            // arrange
            var containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);

            containerMock.Setup(c => c.Update(It.IsAny <IHateoasRegistration>()));
            var registration = new HateoasRegistration <TestModel>(null, null, containerMock.Object);
            var builder      = new ExpressionBuilder <TestModel>(registration);

            var fluentResult = builder.Get <TestModelController>();

            containerMock.ResetCalls();

            // act
            fluentResult.AsCollection();
            var expression = builder.GetExpression();

            // assert
            Assert.IsNotNull(expression);
            Assert.IsTrue(expression.Collection);
            containerMock.Verify(c => c.Update(It.IsAny <IHateoasRegistration>()), Times.Once);
        }
        public void GetWithCustomGetAllMethodWithTwoParametersSelectorShouldSaveControllerAndSetHttpMethodGet()
        {
            // arrange
            var containerMock = new Mock <IHateoasContainer>(MockBehavior.Strict);

            containerMock.Setup(c => c.Update(It.IsAny <IHateoasRegistration>()));
            var registration = new HateoasRegistration <TestModel>(null, null, containerMock.Object);
            var builder      = new ExpressionBuilder <TestModel>(registration);

            // act
            Expression <Func <TestModelController, Func <TestModelFilter, TestModelSorter, object> > > getAllExpression = c => c.GetAll;

            builder.Get(getAllExpression);
            var expression = builder.GetExpression();

            // assert
            Assert.IsNotNull(expression);

            Assert.AreEqual(typeof(TestModelController), expression.Controller);
            Assert.AreEqual(HttpMethod.Get, expression.HttpMethod);
            Assert.AreEqual(getAllExpression, expression.Action);
            containerMock.Verify(c => c.Update(It.IsAny <IHateoasRegistration>()), Times.Once);
        }
        // public static HateoasExpression<TModel> Create<TModel>(HateoasRegistration<TModel> registration)
        // {
        //     return new HateoasExpression<TModel>(registration);
        // }

        public static ExpressionBuilder <TModel> CreateBuilder <TModel>(HateoasRegistration <TModel> registration)
        {
            return(new ExpressionBuilder <TModel>(registration));
        }