public void Validate_FTSQueryIsBlank_ThrowsBadRequestException() { // Arrange var criteriaValidator = new CriteriaValidator(); var searchOption = SearchOption.FullTextSearch; var searchCriteria = new FullTextSearchCriteria { Query = " ", ProjectIds = new[] { 1 } }; BadRequestException badRequestException = null; // Act try { criteriaValidator.Validate(searchOption, true, searchCriteria, ServiceConstants.MinSearchQueryCharLimit); } catch (BadRequestException bre) { badRequestException = bre; } // Assert Assert.IsNotNull(badRequestException, "Bad request exception should have been thrown"); Assert.IsTrue(badRequestException.ErrorCode == ErrorCodes.IncorrectSearchCriteria); }
public async Task FullTextMetaData_WithoutItemTypesThrowsSqlException_SqlExceptionReThrown() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "test", ProjectIds = new[] { 1 } }; var sqlException = SqlExceptionCreator.NewSqlException(-2146232060); var itemSearchRepository = CreateFullTextSearchRepositoryWithException <MetaDataSearchResult>(sqlException); SqlException thrownException = null; // Act try { await itemSearchRepository.FullTextMetaData(UserId, searchCriteria); } catch (SqlException exception) { thrownException = exception; } // Assert Assert.IsNotNull(thrownException, "sqlException != null"); Assert.IsTrue(thrownException.ErrorCode == -2146232060, "Timeout exception should occur"); }
public void Validate_FTSQueryIsValid_Passes() { // Arrange var criteriaValidator = new CriteriaValidator(); var searchOption = SearchOption.FullTextSearch; var searchCriteria = new FullTextSearchCriteria { Query = "12345678901234567890123456789012345678901234567890", ProjectIds = new[] { 1 } }; Exception exception = null; // Act try { criteriaValidator.Validate(searchOption, true, searchCriteria, ServiceConstants.MinSearchQueryCharLimit); } catch (Exception ex) { exception = ex; } // Assert Assert.IsNull(exception, "Exception should not have been thrown"); }
public async Task FullTextMetaData_RepoThrowsException_LogShouldBeCalled() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "empty", ProjectIds = new[] { 1 } }; var logMock = new Mock <IServiceLogRepository>(MockBehavior.Strict); logMock.Setup(t => t.LogError(It.IsAny <string>(), It.IsAny <Exception>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>())).Returns(Task.Delay(1)); var exceptionToBeThrown = new Exception("MyException"); var controller = CreateControllerForExceptionCases(logMock, exceptionToBeThrown); Exception actualException = null; // Act try { await controller.SearchFullText(searchCriteria, 10, 1); } catch (Exception ex) { actualException = ex; } // Assert Assert.IsNotNull(actualException); Assert.AreEqual(exceptionToBeThrown.Message, actualException.Message, "Incorrect exception was thrown"); logMock.Verify(t => t.LogError(It.IsAny <string>(), It.IsAny <Exception>(), It.IsAny <string>(), It.IsAny <string>(), It.IsAny <int>()), Times.Exactly(1)); }
public async Task <MetaDataSearchResultSet> FullTextMetaData([FromBody] FullTextSearchCriteria searchCriteria, int?pageSize = null) { // get the UserId from the session int userId = ValidateAndExtractUserId(); _criteriaValidator.Validate(SearchOption.FullTextSearch, ModelState.IsValid, searchCriteria, ServiceConstants.MinSearchQueryCharLimit); int searchPageSize = GetPageSize(_searchConfigurationProvider, pageSize); try { var results = await _itemSearchRepository.FullTextMetaData(userId, searchCriteria); results.PageSize = searchPageSize; results.TotalPages = results.TotalCount >= 0 ? (int)Math.Ceiling((double)results.TotalCount / searchPageSize) : -1; return(results); } catch (Exception ex) { await Log.LogError(LogSource, ex); throw; } }
public async Task FullTextMetaData_WithoutItemTypes_ReturnsResults() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "test", ProjectIds = new[] { 1 } }; MetaDataSearchResult[] queryResult = { new MetaDataSearchResult() }; int?[] queryResult2 = { 1 }; var itemSearchRepository = CreateFullTextSearchRepository(searchCriteria, queryResult, queryResult2); // Act var result = await itemSearchRepository.FullTextMetaData(UserId, searchCriteria); // Assert CollectionAssert.AreEqual(queryResult.ToList(), result.Items.ToList()); Assert.AreEqual(queryResult2[0], result.TotalCount); }
public async Task SearchFullText_WithItemTypes_ReturnsResults() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "test", ProjectIds = new[] { 1 }, ItemTypeIds = new[] { 10, 20, 30 } }; FullTextSearchResult[] queryResult = { new FullTextSearchResult() }; var itemSearchRepository = CreateFullTextSearchRepository(searchCriteria, queryResult); // Act var result = await itemSearchRepository.SearchFullText(UserId, searchCriteria, Page, PageSize); // Assert CollectionAssert.AreEqual(queryResult, result.Items.ToList()); Assert.AreEqual(Page, result.Page); Assert.AreEqual(queryResult.Length, result.PageItemCount); Assert.AreEqual(PageSize, result.PageSize); }
private void ValidateFullTextCriteria(bool modelStateIsValid, FullTextSearchCriteria searchCriteria, int minSearchQueryLimit = 1) { if (IsCriteriaQueryInvalid(modelStateIsValid, searchCriteria, minSearchQueryLimit, ServiceConstants.MaxSearchQueryCharLimit) || !searchCriteria.ProjectIds.Any()) { throw new BadRequestException("Please provide correct search criteria", ErrorCodes.IncorrectSearchCriteria); } }
private static IItemSearchRepository CreateFullTextSearchRepository <T>( FullTextSearchCriteria searchCriteria, ICollection <T> queryResult, ICollection <int?> queryResult2 = null) { var connectionWrapper = new SqlConnectionWrapperMock(); connectionWrapper.SetupQueryAsync("SearchFullText", new Dictionary <string, object> { { "predefineds", SqlItemSearchRepository.Predefineds }, { "page", Page }, { "pageSize", PageSize }, { "maxItems", MaxItems }, }, queryResult); connectionWrapper.SetupQueryMultipleAsync("SearchFullTextMetaData", new Dictionary <string, object> { { "predefineds", SqlItemSearchRepository.Predefineds }, }, new Tuple <IEnumerable <T>, IEnumerable <int?> >(queryResult, queryResult2)); if (searchCriteria.ItemTypeIds != null) { connectionWrapper.SetupQueryAsync("SearchFullTextByItemTypes", new Dictionary <string, object> { { "predefineds", SqlItemSearchRepository.Predefineds }, { "page", Page }, { "pageSize", PageSize }, { "maxItems", MaxItems }, { "itemTypeIds", SqlConnectionWrapper.ToDataTable(searchCriteria.ItemTypeIds) } }, queryResult); connectionWrapper.SetupQueryMultipleAsync("SearchFullTextByItemTypesMetaData", new Dictionary <string, object> { { "predefineds", SqlItemSearchRepository.Predefineds }, { "itemTypeIds", SqlConnectionWrapper.ToDataTable(searchCriteria.ItemTypeIds) } }, new Tuple <IEnumerable <T>, IEnumerable <int?> >(queryResult, queryResult2)); } var configuration = new Mock <ISearchConfiguration>(); configuration.Setup(c => c.MaxItems).Returns(MaxItems.ToStringInvariant()); configuration.Setup(c => c.MaxSearchableValueStringSize).Returns(MaxSearchableValueStringSize.ToStringInvariant()); return(new SqlItemSearchRepository(connectionWrapper.Object, configuration.Object)); }
public async Task FullTextMetaData_PageSizeNegative_ReturnsConstant() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "empty", ProjectIds = new[] { 1 } }; var controller = CreateController(); // Act var result = await controller.FullTextMetaData(searchCriteria, -1); // Assert Assert.IsNotNull(result, "Result was not retrieved"); Assert.AreEqual(ServiceConstants.SearchPageSize, result.PageSize); }
public async Task SearchFullText_RequestPositivePage_ReturnsPageOne() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "empty", ProjectIds = new[] { 1 } }; var controller = CreateController(); // Act var result = await controller.SearchFullText(searchCriteria, 10, 1); // Assert Assert.IsNotNull(result, "Result was not retrieved"); Assert.AreEqual(10, result.Page); }
public async Task SearchFullText_50PageSize_ReturnsConstant() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "empty", ProjectIds = new[] { 1 } }; var controller = CreateController(); // Act var result = await controller.SearchFullText(searchCriteria, null, 50); // Assert Assert.IsNotNull(result, "Result was not retrieved"); Assert.AreEqual(50, result.PageSize); }
/// <summary> /// Return metadata for a Full Text Search /// </summary> /// <param name="userId"></param> /// <param name="searchCriteria">SearchCriteria object</param> /// <returns>FullTextSearchMetaDataResult</returns> public async Task <MetaDataSearchResultSet> FullTextMetaData(int userId, FullTextSearchCriteria searchCriteria) { string sql; var param = new DynamicParameters(); param.Add("@userId", userId); param.Add("@query", GetQuery(searchCriteria.Query)); param.Add("@projectIds", SqlConnectionWrapper.ToDataTable(searchCriteria.ProjectIds)); param.Add("@predefineds", Predefineds); param.Add("@primitiveItemTypePredefineds", PrimitiveItemTypePredefineds); param.Add("@maxItems", _searchConfigurationProvider.MaxItems); param.Add("@maxSearchableValueStringSize", _searchConfigurationProvider.MaxSearchableValueStringSize); if (searchCriteria.ItemTypeIds?.ToArray().Length > 0) { param.Add("@itemTypeIds", SqlConnectionWrapper.ToDataTable(searchCriteria.ItemTypeIds)); sql = "SearchFullTextByItemTypesMetaData"; } else { sql = "SearchFullTextMetaData"; } try { var result = await _connectionWrapper.QueryMultipleAsync <MetaDataSearchResult, int?>(sql, param, commandType : CommandType.StoredProcedure, commandTimeout : _searchConfigurationProvider.SearchTimeout); return(new MetaDataSearchResultSet { Items = result.Item1, TotalCount = result.Item2.ElementAt(0) ?? 0, }); } catch (SqlException sqlException) { switch (sqlException.Number) { // Sql timeout error case ErrorCodes.SqlTimeoutNumber: throw new SqlTimeoutException("Server did not respond with a response in the allocated time. Please try again later.", ErrorCodes.Timeout); } throw; } }
/// <summary> /// Perform a full text search /// </summary> /// <param name="userId"></param> /// <param name="searchCriteria">SearchCriteria object</param> /// <param name="page">Page Number</param> /// <param name="pageSize">Page Size</param> /// <returns></returns> public async Task <FullTextSearchResultSet> SearchFullText(int userId, FullTextSearchCriteria searchCriteria, int page, int pageSize) { string sql; var param = new DynamicParameters(); param.Add("@userId", userId); param.Add("@query", GetQuery(searchCriteria.Query)); param.Add("@projectIds", SqlConnectionWrapper.ToDataTable(searchCriteria.ProjectIds)); param.Add("@predefineds", Predefineds); param.Add("@primitiveItemTypePredefineds", PrimitiveItemTypePredefineds); param.Add("@page", page); param.Add("@pageSize", pageSize); param.Add("@maxItems", _searchConfigurationProvider.MaxItems); param.Add("@maxSearchableValueStringSize", _searchConfigurationProvider.MaxSearchableValueStringSize); if (searchCriteria.ItemTypeIds?.ToArray().Length > 0) { param.Add("@itemTypeIds", SqlConnectionWrapper.ToDataTable(searchCriteria.ItemTypeIds)); sql = "SearchFullTextByItemTypes"; } else { sql = "SearchFullText"; } try { var items = (await _connectionWrapper.QueryAsync <FullTextSearchResult>(sql, param, commandType: CommandType.StoredProcedure, commandTimeout: _searchConfigurationProvider.SearchTimeout)).ToList(); return(new FullTextSearchResultSet { Items = items, Page = page, PageItemCount = items.Count, PageSize = pageSize }); } catch (SqlException sqlException) { switch (sqlException.Number) { // Sql timeout error case ErrorCodes.SqlTimeoutNumber: throw new SqlTimeoutException("Server did not respond with a response in the allocated time. Please try again later.", ErrorCodes.Timeout); } throw; } }
public async Task <FullTextSearchResultSet> SearchFullText([FromBody] FullTextSearchCriteria searchCriteria, int?page = null, int?pageSize = null) { // get the UserId from the session var userId = ValidateAndExtractUserId(); _criteriaValidator.Validate(SearchOption.FullTextSearch, ModelState.IsValid, searchCriteria, ServiceConstants.MinSearchQueryCharLimit); int searchPageSize = GetPageSize(_searchConfigurationProvider, pageSize); int searchPage = GetStartCounter(page, 1, 1); try { return(await _itemSearchRepository.SearchFullText(userId, searchCriteria, searchPage, searchPageSize)); } catch (Exception ex) { await Log.LogError(LogSource, ex); throw; } }
public async Task SearchFullText_SearchCriteriaIsLessThanThreeCharacters_BadRequest() { // Arrange var searchCriteria = new FullTextSearchCriteria { Query = "12", ProjectIds = new[] { 1 } }; var controller = CreateController(); // Act BadRequestException badRequestException = null; try { await controller.SearchFullText(searchCriteria, null, -1); } catch (BadRequestException e) { badRequestException = e; } // Assert Assert.IsNotNull(badRequestException, "Bad Request Exception should have been thrown"); Assert.AreEqual(ErrorCodes.IncorrectSearchCriteria, badRequestException.ErrorCode, "IncorrectSearchCriteria should be provided as Error code"); }