public async Task Handle_DoesNotReturnPromptsWithParents(int subScenarioAmount)
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = 20, IncludeDrafts = true
            };
            List <Prompt>?prompts = GeneratePromptData();
            Prompt?       parent  = prompts[0];

            for (var i = 0; i < subScenarioAmount; i++)
            {
                prompts.Add(new Prompt {
                    Parent = parent
                });
            }

            DbContext.Prompts.AddRange(prompts);
            DbContext.Prompts.Add(new Prompt {
                IsDraft = true
            });
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(16, actual.Results.Count);
        }
        public async Task Handle_ReturnsInDateDescendingOrder_WhenOrderByIsSetToNewest()
        {
            //arrange
            var latestPrompt = new Prompt {
                DateCreated = DateTime.UtcNow
            };
            var midPrompt = new Prompt {
                DateCreated = DateTime.UtcNow.AddDays(-1)
            };
            var earliestPrompt = new Prompt {
                DateCreated = DateTime.UtcNow.AddDays(-2)
            };

            DbContext.Prompts.AddRange(latestPrompt, midPrompt, earliestPrompt);
            await DbContext.SaveChangesAsync();

            var query = new SearchPromptsQuery {
                OrderBy = SearchOrderBy.Newest
            };

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(latestPrompt.Id, actual.Results[0].Id);
            Assert.Equal(midPrompt.Id, actual.Results[1].Id);
            Assert.Equal(earliestPrompt.Id, actual.Results[2].Id);
        }
        Handle_ReturnsInDateAscendingOrder_WhenOrderByIsSetToNewest_AndReverseIsSetToTrue_AndPromptsHaveBothDateCreatedAndDatePublished()
        {
            //arrange
            var midPrompt = new Prompt {
                DateCreated = DateTime.UtcNow
            };
            var earliestPrompt = new Prompt {
                DateCreated = DateTime.UtcNow.AddDays(-1)
            };
            var latestPrompt = new Prompt
            {
                PublishDate = DateTime.UtcNow.AddDays(1), DateCreated = DateTime.UtcNow.AddDays(-2)
            };

            DbContext.Prompts.AddRange(latestPrompt, midPrompt, earliestPrompt);
            await DbContext.SaveChangesAsync();

            var query = new SearchPromptsQuery {
                OrderBy = SearchOrderBy.Newest, Reverse = true
            };

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(latestPrompt.Id, actual.Results[2].Id);
            Assert.Equal(midPrompt.Id, actual.Results[1].Id);
            Assert.Equal(earliestPrompt.Id, actual.Results[0].Id);
        }
        public async Task Handle_ReturnsEmptyResults_AndSinglePage_WhenThereAreNoEntriesInTheDatabase()
        {
            //arrange
            var query = new SearchPromptsQuery();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Empty(actual.Results);
            Assert.Equal(1, actual.TotalPages);
        }
        public async Task Handle_ReturnsReverseDateOrderedPrompts_WhenReverseIsSet()
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = 15, Reverse = true
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.True(actual.Results[^ 1].DateCreated > actual.Results[0].DateCreated);
        public async Task Handle_ReturnsEmptyResults_WhenGivenAUserIdWithNoPrompts()
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = 15, UserId = 0
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Empty(actual.Results);
        }
        Handle_ReturnsOneResult_WhenThereAreFifteenPrompts_AndPageIsDefault_AndPageSizeIsSetToANegativeNumber(
            int pageSize)
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = pageSize
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Single(actual.Results);
        }
        public async Task Handle_ReturnsFiveResults_WhenNsfwIsEnabled_AndThereAreFiveNsfwPrompts()
        {
            //arrange
            var query = new SearchPromptsQuery {
                Nsfw = SearchNsfw.NsfwOnly
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(5, actual.Results.Count);
            Assert.Equal(1, actual.TotalPages);
        }
        public async Task Handle_ReturnsFifteenResults_WhenThereFifteenPrompts_AndTheDefaultPageIsFifteen()
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = 15
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(15, actual.Results.Count);
            Assert.Equal(1, actual.TotalPages);
        }
        public async Task Handle_ReturnsResultsThatMatchTagsFuzzily_WhenGivenAListOfTags_AndFuzzyIsTrue(string[] tags,
                                                                                                        int expectedAmount)
        {
            //arrange
            var tagList = tags.ToList();
            var query   = new SearchPromptsQuery {
                PageSize = 15, Tags = tagList, TagsFuzzy = true
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(expectedAmount, actual.Results.Count);
        }
        Handle_ReturnsPromptsWithTitleContainingSearchQuery_WhenThereArePromptsWithTheSearchQueryInTheTitle(
            string titleQuery, int expectedAmount)
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = 15, Search = titleQuery
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(expectedAmount, actual.Results.Count);
            Assert.True(actual.Results.All(prompt =>
                                           prompt.Title.Contains(titleQuery, StringComparison.OrdinalIgnoreCase)));
        }
        public async Task Handle_ReturnsPromptsBelongingToUser_WhenGivenAValidUserId()
        {
            //arrange
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            var userId = DbContext.Users.First().Id;
            var query  = new SearchPromptsQuery {
                PageSize = 15, UserId = DbContext.Users.First().Id
            };

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(5, actual.Results.Count);
            Assert.True(actual.Results.All(e => e.OwnerId == userId));
        }
        public async Task Handle_ReturnsDrafts_WhenIncludesDraftsIsTrue()
        {
            //arrange
            var query = new SearchPromptsQuery {
                PageSize = 20, IncludeDrafts = true
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            DbContext.Prompts.Add(new Prompt {
                IsDraft = true
            });
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(16, actual.Results.Count);
            Assert.Contains(actual.Results, e => e.IsDraft);
        }
        public async Task Handle_ReturnsResultsThatMatchTagsExactly_WhenGivenAListOfTags(string[] tags,
                                                                                         int expectedAmount)
        {
            //arrange
            var tagList = tags.ToList();
            var query   = new SearchPromptsQuery {
                PageSize = 15, Tags = tagList
            };
            List <Prompt>?prompts = GeneratePromptData();

            DbContext.Prompts.AddRange(prompts);
            await DbContext.SaveChangesAsync();

            //act
            SearchPromptsViewModel?actual = await _handler.Handle(query);

            //assert
            Assert.Equal(expectedAmount, actual.Results.Count);
            Assert.True(actual.Results.All(prompt =>
                                           prompt.SearchPromptsTagViewModel.Any(tag => tagList.Contains(tag.Name))));
        }