public async Task ProductCategoriesWorkflow()
        {
            using var client = await TestBootstrapper.CreateTestClientWithInMemoryDb();

            await TestRecordsCreator.CreateCategoryAsync(client, "stocks/Germany/Dax 30");

            var getCategoriesResponse = await client.GetAsync("/api/product-categories");

            var categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                             .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Equal(3, categories.Count);
            Assert.True(categories.First(c => c.Id == "stocks.germany.dax_30").IsLeaf);
            Assert.False(categories.First(c => c.Id == "stocks.germany").IsLeaf);
            Assert.False(categories.First(c => c.Id == "stocks").IsLeaf);

            var deleteRequest = new DeleteProductCategoryRequest()
            {
                UserName = "******",
            };

            var leafCategoryId = "stocks.germany.dax_30";

            await client.DeleteAsJsonAsync($"/api/product-categories/{leafCategoryId}", deleteRequest);

            getCategoriesResponse = await client.GetAsync("/api/product-categories");

            categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                         .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Equal(2, categories.Count);
            Assert.True(categories.First(c => c.Id == "stocks.germany").IsLeaf);
            Assert.False(categories.First(c => c.Id == "stocks").IsLeaf);
        }
        public async Task ProductCategories_CannotDeleteCategoryWithAttachedProducts_Workflow()
        {
            _underlyingsCacheMock.Setup(x => x.GetByMdsCode(It.IsAny <string>()))
            .Returns(new UnderlyingsCacheModel()
            {
                MdsCode         = "mds-code",
                TradingCurrency = "EUR",
            });

            _assetTypesRepositoryMock.Setup(x => x.ExistsAsync(It.IsAny <string>()))
            .ReturnsAsync(true);

            using var client = await TestBootstrapper.CreateTestClientWithInMemoryDb(builder =>
            {
                builder.RegisterInstance(_underlyingsCacheMock.Object).As <IUnderlyingsCache>().SingleInstance();
                builder.RegisterInstance(_assetTypesRepositoryMock.Object).As <IAssetTypesRepository>().SingleInstance();
            });

            var category = "stocks";

            await TestRecordsCreator.CreateCurrencyAsync(client, "EUR");

            await TestRecordsCreator.CreateMarketSettings(client, "market");

            await TestRecordsCreator.CreateTickFormula(client, "tick_formula");

            // asset type is mocked
            await TestRecordsCreator.CreateProductAsync(client, "product1", category);

            var getCategoriesResponse = await client.GetAsync("/api/product-categories");

            var categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                             .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Single(categories);

            var deleteRequest = new DeleteProductCategoryRequest()
            {
                UserName = "******",
            };

            var deleteCategoryResponse =
                (await client.DeleteAsJsonAsync($"/api/product-categories/{category}", deleteRequest));
            var errorCode = (await deleteCategoryResponse.Content.ReadAsStringAsync())
                            .DeserializeJson <ErrorCodeResponse <ProductCategoriesErrorCodesContract> >().ErrorCode;

            Assert.Equal(ProductCategoriesErrorCodesContract.CannotDeleteCategoryWithAttachedProducts, errorCode);

            getCategoriesResponse = await client.GetAsync("/api/product-categories");

            categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                         .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Single(categories);
        }
        public async Task ProductCategories_ParentHasAttachedProducts_Workflow()
        {
            _underlyingsCacheMock.Setup(x => x.GetByMdsCode(It.IsAny <string>()))
            .Returns(new UnderlyingsCacheModel()
            {
                MdsCode         = "mds-code",
                TradingCurrency = "EUR",
            });

            _assetTypesRepositoryMock.Setup(x => x.ExistsAsync(It.IsAny <string>()))
            .ReturnsAsync(true);

            using var client = await TestBootstrapper.CreateTestClientWithInMemoryDb(builder =>
            {
                builder.RegisterInstance(_underlyingsCacheMock.Object).As <IUnderlyingsCache>().SingleInstance();
                builder.RegisterInstance(_assetTypesRepositoryMock.Object).As <IAssetTypesRepository>().SingleInstance();
            });

            var categoryWithProduct = "stocks/germany";
            var category            = "stocks/germany/dax 30";

            await TestRecordsCreator.CreateCurrencyAsync(client, "EUR");

            await TestRecordsCreator.CreateMarketSettings(client, "market");

            await TestRecordsCreator.CreateTickFormula(client, "tick_formula");

            // asset type is mocked
            await TestRecordsCreator.CreateProductAsync(client, "product1", categoryWithProduct);

            var errorCode = await TestRecordsCreator.CreateCategoryAsync(client, category);

            Assert.Equal(ProductCategoriesErrorCodesContract.ParentHasAttachedProducts, errorCode);

            var getCategoriesResponse = await client.GetAsync("/api/product-categories");

            var categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                             .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Collection(categories,
                              x => { Assert.Equal("stocks", x.Id); },
                              x1 => { Assert.Equal("stocks.germany", x1.Id); });
        }
        public async Task ProductCategories_CannotDeleteNonLeafCategory_Workflow()
        {
            using var client = await TestBootstrapper.CreateTestClientWithInMemoryDb();

            var notLeafCategory = "stocks";
            var category        = "stocks/germany";

            await TestRecordsCreator.CreateCategoryAsync(client, category);

            var getCategoriesResponse = await client.GetAsync("/api/product-categories");

            var categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                             .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Collection(categories,
                              x => { Assert.Equal("stocks", x.Id); },
                              x1 => { Assert.Equal("stocks.germany", x1.Id); });

            var deleteRequest = new DeleteProductCategoryRequest()
            {
                UserName = "******",
            };

            var deleteCategoryResponse =
                (await client.DeleteAsJsonAsync($"/api/product-categories/{notLeafCategory}", deleteRequest));
            var errorCode = (await deleteCategoryResponse.Content.ReadAsStringAsync())
                            .DeserializeJson <ErrorCodeResponse <ProductCategoriesErrorCodesContract> >().ErrorCode;

            Assert.Equal(ProductCategoriesErrorCodesContract.CannotDeleteNonLeafCategory, errorCode);

            getCategoriesResponse = await client.GetAsync("/api/product-categories");

            categories = (await getCategoriesResponse.Content.ReadAsStringAsync())
                         .DeserializeJson <GetProductCategoriesResponse>().ProductCategories;

            Assert.Collection(categories,
                              x => { Assert.Equal("stocks", x.Id); },
                              x1 => { Assert.Equal("stocks.germany", x1.Id); });
        }
        public async Task TestClientProfileSettingsWorkflow()
        {
            _brokerSettingsApiMock.Setup(x => x.GetByIdAsync(It.IsAny <string>()))
            .ReturnsAsync(new GetBrokerSettingsByIdResponse
            {
                ErrorCode      = BrokerSettingsErrorCodesContract.None,
                BrokerSettings = new BrokerSettingsContract {
                    RegulationId = RegulationId
                }
            });

            _regulatoryTypesApiMock.Setup(x => x.GetRegulatoryTypeByIdAsync(RegulatoryTypeId))
            .ReturnsAsync(new GetRegulatoryTypeByIdResponse
            {
                RegulatoryType = new RegulatoryTypeContract
                {
                    RegulationId = RegulationId
                }
            });

            _regulatoryProfilesApiMock.Setup(x => x.GetRegulatoryProfileByIdAsync(RegulatoryProfileId))
            .ReturnsAsync(new GetRegulatoryProfileByIdResponse
            {
                RegulatoryProfile = new RegulatoryProfileContract
                {
                    RegulationId = RegulationId
                }
            });

            _regulatorySettingsApiMock.Setup(x => x.GetRegulatorySettingsByIdsAsync(It.IsAny <string>(), It.IsAny <string>()))
            .ReturnsAsync(new GetRegulatorySettingsByIdsResponse()
            {
                RegulatorySettings = new RegulatorySettingsContract()
                {
                    IsAvailable      = true,
                    MarginMinPercent = MarginMinPercent,
                }
            });

            _regulatorySettingsApiMock.Setup(x => x.GetRegulatorySettingsByRegulationAsync(It.IsAny <string>()))
            .ReturnsAsync(new GetRegulatorySettingsResponse()
            {
                RegulatorySettings = new List <RegulatorySettingsContract>
                {
                    new RegulatorySettingsContract
                    {
                        MarginMinPercent = MarginMinPercent,
                        IsAvailable      = true,
                        TypeId           = RegulatoryTypeId,
                        ProfileId        = RegulatoryProfileId
                    }
                }
            });

            _underlyingCategoriesCacheMock.Setup(x => x.Get()).ReturnsAsync(new List <UnderlyingCategoryCacheModel>
            {
                new UnderlyingCategoryCacheModel
                {
                    Id = UnderlyingCategoryId,
                    FinancingFeesFormula = ""
                }
            });

            _underlyingCategoriesApiMock.Setup(x => x.GetAllAsync()).ReturnsAsync(new GetUnderlyingCategoriesResponse
            {
                UnderlyingCategories = new List <UnderlyingCategoryContract>
                {
                    new UnderlyingCategoryContract
                    {
                        Id = UnderlyingCategoryId,
                        FinancingFeesFormula = ""
                    }
                }
            });

            var client = await TestBootstrapper.CreateTestClientWithInMemoryDb(builder =>
            {
                builder.RegisterInstance(_brokerSettingsApiMock.Object).As <IBrokerSettingsApi>().SingleInstance();
                builder.RegisterInstance(_regulationsApiMock.Object).As <IRegulationsApi>().SingleInstance();
                builder.RegisterInstance(_regulatoryTypesApiMock.Object).As <IRegulatoryTypesApi>().SingleInstance();
                builder.RegisterInstance(_regulatorySettingsApiMock.Object).As <IRegulatorySettingsApi>().SingleInstance();
                builder.RegisterInstance(_regulatoryProfilesApiMock.Object).As <IRegulatoryProfilesApi>().SingleInstance();
                builder.RegisterInstance(_underlyingCategoriesApiMock.Object).As <IUnderlyingCategoriesApi>().SingleInstance();
                builder.RegisterInstance(_underlyingCategoriesCacheMock.Object).As <IUnderlyingCategoriesCache>().SingleInstance();
            });

            await TestRecordsCreator.CreateClientProfileAsync(client, RegulatoryProfileId, ClientProfileId, true);

            await TestRecordsCreator.CreateAssetTypeAsync(client, RegulatoryTypeId, AssetTypeId, UnderlyingCategoryId);

            var updateClientProfileSettingsRequest = new UpdateClientProfileSettingsRequest
            {
                Margin      = MarginRate,
                IsAvailable = true,
                Username    = "******"
            };

            await client.PutAsync($"/api/client-profile-settings/profile/{ClientProfileId}/type/{AssetTypeId}",
                                  updateClientProfileSettingsRequest.ToJsonStringContent());

            await TestRecordsCreator.CreateAssetTypeAsync(client, RegulatoryTypeId, SecondAssetTypeId,
                                                          UnderlyingCategoryId, AssetTypeId);

            await TestRecordsCreator.CreateClientProfileAsync(client, RegulatoryProfileId, SecondClientProfileId, false, ClientProfileId);

            //Get all client profile settings for this regulation
            var getClientProfileSettingsRequest = await client.GetAsync($"/api/client-profile-settings");

            var clientProfileSettings = (await getClientProfileSettingsRequest.Content.ReadAsStringAsync())
                                        .DeserializeJson <GetAllClientProfileSettingsResponse>().ClientProfileSettings;

            //Check if the result contains settings with copied values from the templates
            var containsSettingsCreatedFromProfileTemplate = clientProfileSettings.Any(s =>
                                                                                       s.IsAvailable && s.AssetTypeId == AssetTypeId && s.ClientProfileId == SecondClientProfileId &&
                                                                                       s.Margin == MarginRate);

            var containsSettingsCreatedFromTypeTemplate = clientProfileSettings.Any(s =>
                                                                                    s.IsAvailable && s.AssetTypeId == SecondAssetTypeId && s.ClientProfileId == ClientProfileId &&
                                                                                    s.Margin == MarginRate);

            Assert.True(containsSettingsCreatedFromProfileTemplate);
            Assert.True(containsSettingsCreatedFromTypeTemplate);
            Assert.Equal(4, clientProfileSettings.Count);
        }