protected TestObjectsC <TPrimary, TFirstSecondary, TSecondSecondary> CreateTestObjectsC <TPrimary, TFirstSecondary, TSecondSecondary>(
            IHooksDiscovery <TPrimary> primaryDiscovery = null, IHooksDiscovery <TFirstSecondary> firstSecondaryDiscovery = null,
            IHooksDiscovery <TSecondSecondary> secondSecondaryDiscovery = null, DbContextOptions <HooksDbContext> repoDbContextOptions = null)
            where TPrimary : class, IIdentifiable <int>
            where TFirstSecondary : class, IIdentifiable <int>
            where TSecondSecondary : class, IIdentifiable <int>
        {
            // creates the resource definition mock and corresponding for a given set of discoverable hooks
            Mock <IResourceHookContainer <TPrimary> >         primaryResource         = CreateResourceDefinition <TPrimary>();
            Mock <IResourceHookContainer <TFirstSecondary> >  firstSecondaryResource  = CreateResourceDefinition <TFirstSecondary>();
            Mock <IResourceHookContainer <TSecondSecondary> > secondSecondaryResource = CreateResourceDefinition <TSecondSecondary>();

            // mocking the genericServiceFactory and JsonApiContext and wiring them up.
            (Mock <ITargetedFields> ufMock, Mock <IEnumerable <IQueryConstraintProvider> > constraintsMock, Mock <IGenericServiceFactory> gpfMock,
             IJsonApiOptions options) = CreateMocks();

            HooksDbContext dbContext = repoDbContextOptions != null ? new HooksDbContext(repoDbContextOptions) : null;

            IResourceGraph resourceGraph = new ResourceGraphBuilder(new JsonApiOptions(), NullLoggerFactory.Instance).Add <TPrimary>().Add <TFirstSecondary>()
                                           .Add <TSecondSecondary>().Build();

            SetupProcessorFactoryForResourceDefinition(gpfMock, primaryResource.Object, primaryDiscovery, dbContext, resourceGraph);
            SetupProcessorFactoryForResourceDefinition(gpfMock, firstSecondaryResource.Object, firstSecondaryDiscovery, dbContext, resourceGraph);
            SetupProcessorFactoryForResourceDefinition(gpfMock, secondSecondaryResource.Object, secondSecondaryDiscovery, dbContext, resourceGraph);

            var execHelper      = new HookContainerProvider(gpfMock.Object, ResourceGraph, options);
            var traversalHelper = new NodeNavigator(ResourceGraph, ufMock.Object);
            var hookExecutor    = new ResourceHookExecutor(execHelper, traversalHelper, ufMock.Object, constraintsMock.Object, ResourceGraph);

            return(new TestObjectsC <TPrimary, TFirstSecondary, TSecondSecondary>(constraintsMock, hookExecutor, primaryResource, firstSecondaryResource,
                                                                                  secondSecondaryResource));
        }
        private void ResolveInverseRelationships(HooksDbContext context)
        {
            IEnumerable <DbContextResolver <HooksDbContext> > dbContextResolvers = new DbContextResolver <HooksDbContext>(context).AsEnumerable();
            var inverseRelationships = new InverseNavigationResolver(ResourceGraph, dbContextResolvers);

            inverseRelationships.Resolve();
        }
        private IDbContextResolver CreateTestDbResolver(HooksDbContext dbContext)
        {
            var mock = new Mock <IDbContextResolver>();

            mock.Setup(resolver => resolver.GetContext()).Returns(dbContext);
            return(mock.Object);
        }
        private IResourceReadRepository <TModel, int> CreateTestRepository <TModel>(HooksDbContext dbContext, IResourceGraph resourceGraph)
            where TModel : class, IIdentifiable <int>
        {
            var resourceFactory         = new TestResourceFactory();
            IDbContextResolver resolver = CreateTestDbResolver(dbContext);
            var targetedFields          = new TargetedFields();

            return(new EntityFrameworkCoreRepository <TModel, int>(targetedFields, resolver, resourceGraph, resourceFactory,
                                                                   Enumerable.Empty <IQueryConstraintProvider>(), NullLoggerFactory.Instance));
        }
        protected DbContextOptions <HooksDbContext> InitInMemoryDb(Action <DbContext> seeder)
        {
            DbContextOptions <HooksDbContext> options = new DbContextOptionsBuilder <HooksDbContext>().UseInMemoryDatabase("repository_mock").Options;

            using var context = new HooksDbContext(options);

            seeder(context);
            ResolveInverseRelationships(context);

            return(options);
        }
        private void SetupProcessorFactoryForResourceDefinition <TModel>(Mock <IGenericServiceFactory> processorFactory,
                                                                         IResourceHookContainer <TModel> modelResource, IHooksDiscovery <TModel> discovery, HooksDbContext dbContext = null,
                                                                         IResourceGraph resourceGraph = null)
            where TModel : class, IIdentifiable <int>
        {
            processorFactory.Setup(factory => factory.Get <IResourceHookContainer>(typeof(ResourceHooksDefinition <>), typeof(TModel))).Returns(modelResource);

            processorFactory.Setup(factory => factory.Get <IHooksDiscovery>(typeof(IHooksDiscovery <>), typeof(TModel))).Returns(discovery);

            if (dbContext != null)
            {
                Type idType = ObjectFactory.GetIdType(typeof(TModel));

                if (idType == typeof(int))
                {
                    IResourceReadRepository <TModel, int> repo = CreateTestRepository <TModel>(dbContext, resourceGraph);

                    processorFactory.Setup(factory =>
                                           factory.Get <IResourceReadRepository <TModel, int> >(typeof(IResourceReadRepository <,>), typeof(TModel), typeof(int))).Returns(repo);
                }
                else
                {
                    throw new TypeLoadException("Test not set up properly");
                }
            }
        }