public async Task CanCreateDailyAliases(DateTime utcNow) {
            SystemClock.SetFixedTime(utcNow);
            var index = new DailyEmployeeIndex(_configuration, 1);
            await index.DeleteAsync();
            
            using (new DisposableAction(() => index.DeleteAsync().GetAwaiter().GetResult())) {
                await index.ConfigureAsync();
                var repository = new EmployeeRepository(index.Employee);

                for (int i = 0; i < 35; i += 5) {
                    var employee = await repository.AddAsync(EmployeeGenerator.Generate(createdUtc: utcNow.SubtractDays(i)));
                    Assert.NotNull(employee?.Id);

                    Assert.Equal(1, await index.GetCurrentVersionAsync());
                    var existsResponse = await _client.IndexExistsAsync(index.GetIndex(employee.CreatedUtc));
                    _logger.Trace(() => existsResponse.GetRequest());
                    Assert.True(existsResponse.IsValid);
                    Assert.True(existsResponse.Exists);

                    var aliasesResponse = await _client.GetAliasesAsync(a => a.Index(index.GetIndex(employee.CreatedUtc)));
                    _logger.Trace(() => aliasesResponse.GetRequest());
                    Assert.True(aliasesResponse.IsValid);
                    Assert.Equal(1, aliasesResponse.Indices.Count);

                    var aliases = aliasesResponse.Indices.Values.Single().Select(s => s.Name).ToList();
                    aliases.Sort();

                    Assert.Equal(GetExpectedEmployeeDailyAliases(index, utcNow, employee.CreatedUtc), String.Join(", ", aliases));
                }
            }
        }
        public DateTime? Parse(Match match, DateTime now, bool isUpperLimit) {
            string value = match.Groups["name"].Value.ToLower();
            if (value == "now")
                return now;
            if (value == "today")
                return isUpperLimit ? now.Date.EndOfDay() : now.Date;
            if (value == "yesterday")
                return isUpperLimit ? now.Date.SubtractDays(1).EndOfDay() : now.SubtractDays(1).Date;
            if (value == "tomorrow")
                return isUpperLimit ? now.Date.AddDays(1).EndOfDay() : now.AddDays(1).Date;

            return null;
        }
        private string GetExpectedEmployeeMonthlyAliases(DailyIndex index, DateTime utcNow, DateTime indexDateUtc) {
            var aliases = new List<string> { index.Name, index.GetIndex(indexDateUtc) };
            if (new DateTimeRange(utcNow.SubtractDays(1).StartOfMonth(), utcNow.EndOfMonth()).Contains(indexDateUtc))
                aliases.Add($"{index.Name}-today");

            if (new DateTimeRange(utcNow.SubtractDays(7).StartOfMonth(), utcNow.EndOfMonth()).Contains(indexDateUtc))
                aliases.Add($"{index.Name}-last7days");

            if (new DateTimeRange(utcNow.SubtractDays(30).StartOfMonth(), utcNow.EndOfMonth()).Contains(indexDateUtc))
                aliases.Add($"{index.Name}-last30days");

            if (new DateTimeRange(utcNow.SubtractDays(60).StartOfMonth(), utcNow.EndOfMonth()).Contains(indexDateUtc))
                aliases.Add($"{index.Name}-last60days");

            aliases.Sort();
            return String.Join(", ", aliases);
        }
        public async Task DailyIndexMaxAge(DateTime utcNow) {
            SystemClock.SetFixedTime(utcNow);

            var index = new DailyEmployeeIndex(_configuration, 1);
            index.MaxIndexAge = TimeSpan.FromDays(1);
            await index.DeleteAsync();

            using (new DisposableAction(() => index.DeleteAsync().GetAwaiter().GetResult())) {
                await index.ConfigureAsync();
                
                await index.EnsureIndexAsync(utcNow);
                var existsResponse = await _client.IndexExistsAsync(index.GetIndex(utcNow));
                _logger.Trace(() => existsResponse.GetRequest());
                Assert.True(existsResponse.IsValid);
                Assert.True(existsResponse.Exists);

                await index.EnsureIndexAsync(utcNow.SubtractDays(1));
                existsResponse = await _client.IndexExistsAsync(index.GetIndex(utcNow.SubtractDays(1)));
                _logger.Trace(() => existsResponse.GetRequest());
                Assert.True(existsResponse.IsValid);
                Assert.True(existsResponse.Exists);

                await Assert.ThrowsAsync<ArgumentException>(async () => await index.EnsureIndexAsync(utcNow.SubtractDays(2)));
                existsResponse = await _client.IndexExistsAsync(index.GetIndex(utcNow.SubtractDays(2)));
                _logger.Trace(() => existsResponse.GetRequest());
                Assert.True(existsResponse.IsValid);
                Assert.False(existsResponse.Exists);
            }
        }