public async Task CanDeleteOrphanedEventsByStack()
    {
        var organization = OrganizationData.GenerateSampleOrganization(_billingManager, _plans);
        await _organizationRepository.AddAsync(organization, o => o.ImmediateConsistency());

        var project = await _projectRepository.AddAsync(ProjectData.GenerateSampleProject(), o => o.ImmediateConsistency());

        var stack = await _stackRepository.AddAsync(StackData.GenerateSampleStack(), o => o.ImmediateConsistency());

        await _eventRepository.AddAsync(EventData.GenerateEvents(5000, organization.Id, project.Id, stack.Id), o => o.ImmediateConsistency());

        var orphanedEvents = EventData.GenerateEvents(10000, organization.Id, project.Id).ToList();

        orphanedEvents.ForEach(e => e.StackId = ObjectId.GenerateNewId().ToString());

        await _eventRepository.AddAsync(orphanedEvents, o => o.ImmediateConsistency());

        var eventCount = await _eventRepository.CountAsync(o => o.IncludeSoftDeletes().ImmediateConsistency());

        Assert.Equal(15000, eventCount);

        await GetService <CleanupOrphanedDataJob>().RunAsync();

        eventCount = await _eventRepository.CountAsync(o => o.IncludeSoftDeletes().ImmediateConsistency());

        Assert.Equal(5000, eventCount);
    }
        public async Task CanAddAndGetByCachedAsync()
        {
            await ResetAsync();

            var cache = IoC.GetInstance <ICacheClient>() as InMemoryCacheClient;

            Assert.NotNull(cache);
            await cache.RemoveAllAsync();

            var stack = StackData.GenerateSampleStack();

            Assert.Equal(0, cache.Count);
            await _repository.AddAsync(stack, true);

            Assert.NotNull(stack.Id);
            Assert.Equal(2, cache.Count);
            await _client.RefreshAsync();

            await cache.RemoveAllAsync();

            Assert.Equal(0, cache.Count);
            Assert.NotNull(await _repository.GetByIdAsync(stack.Id, true));
            Assert.Equal(1, cache.Count);

            await _repository.RemoveAllAsync();

            await _client.RefreshAsync();

            Assert.Equal(0, cache.Count);
        }
    public async Task CanCleanupSoftDeletedStack()
    {
        var organization = await _organizationRepository.AddAsync(OrganizationData.GenerateSampleOrganization(_billingManager, _plans), o => o.ImmediateConsistency());

        var project = await _projectRepository.AddAsync(ProjectData.GenerateSampleProject(), o => o.ImmediateConsistency());

        var stack = StackData.GenerateSampleStack();

        stack.IsDeleted = true;
        await _stackRepository.AddAsync(stack, o => o.ImmediateConsistency());

        var persistentEvent = await _eventRepository.AddAsync(EventData.GenerateEvent(organization.Id, project.Id, stack.Id), o => o.ImmediateConsistency());

        await _job.RunAsync();

        Assert.NotNull(await _organizationRepository.GetByIdAsync(organization.Id));
        Assert.NotNull(await _projectRepository.GetByIdAsync(project.Id));
        Assert.Null(await _stackRepository.GetByIdAsync(stack.Id, o => o.IncludeSoftDeletes()));
        Assert.Null(await _eventRepository.GetByIdAsync(persistentEvent.Id, o => o.IncludeSoftDeletes()));
    }
    public async Task CanCleanupEventsOutsideOfRetentionPeriod()
    {
        var organization = OrganizationData.GenerateSampleOrganization(_billingManager, _plans);

        _billingManager.ApplyBillingPlan(organization, _plans.FreePlan);
        await _organizationRepository.AddAsync(organization, o => o.ImmediateConsistency());

        var project = await _projectRepository.AddAsync(ProjectData.GenerateSampleProject(), o => o.ImmediateConsistency());

        var stack = await _stackRepository.AddAsync(StackData.GenerateSampleStack(), o => o.ImmediateConsistency());

        var options         = GetService <AppOptions>();
        var date            = SystemClock.OffsetUtcNow.SubtractDays(options.MaximumRetentionDays);
        var persistentEvent = await _eventRepository.AddAsync(EventData.GenerateEvent(organization.Id, project.Id, stack.Id, date, date, date), o => o.ImmediateConsistency());

        await _job.RunAsync();

        Assert.NotNull(await _organizationRepository.GetByIdAsync(organization.Id));
        Assert.NotNull(await _projectRepository.GetByIdAsync(project.Id));
        Assert.NotNull(await _stackRepository.GetByIdAsync(stack.Id));
        Assert.Null(await _eventRepository.GetByIdAsync(persistentEvent.Id, o => o.IncludeSoftDeletes()));
    }
        public void CanAddAndGetByCached()
        {
            var cache = IoC.GetInstance <ICacheClient>() as InMemoryCacheClient;

            Assert.NotNull(cache);
            cache.FlushAll();

            var stack = StackData.GenerateSampleStack();

            Assert.Equal(0, cache.Count);
            _repository.Add(stack, true);
            Assert.NotNull(stack.Id);
            Assert.Equal(2, cache.Count);
            _client.Refresh();

            cache.FlushAll();
            Assert.Equal(0, cache.Count);
            Assert.NotNull(_repository.GetById(stack.Id, true));
            Assert.Equal(1, cache.Count);

            _repository.RemoveAll();
            Assert.Equal(0, cache.Count);
        }