示例#1
0
        public async Task SendOrganizationPaymentFailedAsync()
        {
            var user         = UserData.GenerateSampleUser();
            var organization = OrganizationData.GenerateSampleOrganization(_billingManager, _plans);

            await _mailer.SendOrganizationPaymentFailedAsync(user, organization);

            await RunMailJobAsync();
        }
示例#2
0
        public async Task SendOrganizationMonthlyOverageNoticeAsync()
        {
            var user         = UserData.GenerateSampleUser();
            var organization = OrganizationData.GenerateSampleOrganization();

            await _mailer.SendOrganizationNoticeAsync(user, organization, true, false);

            await RunMailJobAsync();
        }
示例#3
0
        public async Task SendOrganizationHourlyOverageNoticeAsync()
        {
            var user         = UserData.GenerateSampleUser();
            var organization = OrganizationData.GenerateSampleOrganization(_billingManager, _plans);

            await _mailer.SendOrganizationNoticeAsync(user, organization, false, true);

            await RunMailJobAsync();
        }
示例#4
0
        public async Task SendOrganizationMonthlyOverageNotificationAsync()
        {
            await _mailer.SendOrganizationNoticeAsync(Settings.Current.TestEmailAddress, new OrganizationNotificationModel {
                Organization       = OrganizationData.GenerateSampleOrganization(),
                IsOverMonthlyLimit = true
            });

            await RunMailJobAsync();
        }
示例#5
0
        public async Task SendOrganizationAddedAsync()
        {
            var user         = UserData.GenerateSampleUser();
            var organization = OrganizationData.GenerateSampleOrganization();

            await _mailer.SendOrganizationAddedAsync(user, organization, user);

            await RunMailJobAsync();
        }
示例#6
0
        public async Task CloseInactiveSessions(int defaultInactivePeriodInMinutes, bool willCloseSession, int?sessionHeartbeatUpdatedAgoInSeconds, bool heartbeatClosesSession)
        {
            const string userId = "*****@*****.**";
            var          ev     = GenerateEvent(SystemClock.OffsetNow.SubtractMinutes(5), userId);

            var context = await _pipeline.RunAsync(ev, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject());

            Assert.False(context.HasError, context.ErrorMessage);
            Assert.False(context.IsCancelled);
            Assert.True(context.IsProcessed);

            await _configuration.Client.RefreshAsync(Indices.All);

            var events = await _eventRepository.GetAllAsync();

            Assert.Equal(2, events.Total);
            Assert.Single(events.Documents.Where(e => !String.IsNullOrEmpty(e.GetSessionId())).Select(e => e.GetSessionId()).Distinct());
            var sessionStart = events.Documents.First(e => e.IsSessionStart());

            Assert.Equal(0, sessionStart.Value);
            Assert.False(sessionStart.HasSessionEndTime());

            var utcNow = SystemClock.UtcNow;

            if (sessionHeartbeatUpdatedAgoInSeconds.HasValue)
            {
                await _cache.SetAsync($"Project:{sessionStart.ProjectId}:heartbeat:{userId.ToSHA1()}", utcNow.SubtractSeconds(sessionHeartbeatUpdatedAgoInSeconds.Value));

                if (heartbeatClosesSession)
                {
                    await _cache.SetAsync($"Project:{sessionStart.ProjectId}:heartbeat:{userId.ToSHA1()}-close", true);
                }
            }

            _job.DefaultInactivePeriod = TimeSpan.FromMinutes(defaultInactivePeriodInMinutes);
            Assert.Equal(JobResult.Success, await _job.RunAsync());
            await _configuration.Client.RefreshAsync(Indices.All);

            events = await _eventRepository.GetAllAsync();

            Assert.Equal(2, events.Total);

            sessionStart = events.Documents.First(e => e.IsSessionStart());
            decimal sessionStartDuration = (decimal)(sessionHeartbeatUpdatedAgoInSeconds.HasValue ? (utcNow.SubtractSeconds(sessionHeartbeatUpdatedAgoInSeconds.Value) - sessionStart.Date.UtcDateTime).TotalSeconds : 0);

            if (willCloseSession)
            {
                Assert.Equal(sessionStartDuration, sessionStart.Value);
                Assert.True(sessionStart.HasSessionEndTime());
            }
            else
            {
                Assert.Equal(sessionStartDuration, sessionStart.Value);
                Assert.False(sessionStart.HasSessionEndTime());
            }
        }
示例#7
0
        private async Task CreateEventsAsync(int eventCount, string[] projectIds, decimal?value = -1)
        {
            var events = EventData.GenerateEvents(eventCount, projectIds: projectIds, startDate: SystemClock.OffsetUtcNow.SubtractDays(3), endDate: SystemClock.OffsetUtcNow, value: value);

            foreach (var eventGroup in events.GroupBy(ev => ev.ProjectId))
            {
                await _pipeline.RunAsync(eventGroup, OrganizationData.GenerateSampleOrganization(), ProjectData.GenerateSampleProject());
            }

            await _configuration.Client.RefreshAsync(Indices.All);
        }
示例#8
0
    private async Task CreateEventsAsync(int eventCount, string[] projectIds, decimal?value = -1)
    {
        var events = EventData.GenerateEvents(eventCount, projectIds: projectIds, startDate: SystemClock.OffsetUtcNow.SubtractDays(3), endDate: SystemClock.OffsetUtcNow, value: value);

        foreach (var eventGroup in events.GroupBy(ev => ev.ProjectId))
        {
            await _pipeline.RunAsync(eventGroup, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject());
        }
        await _stackService.SaveStackUsagesAsync();

        await RefreshDataAsync();
    }
示例#9
0
        public async Task WillNotSetLocation()
        {
            var plugin = new GeoPlugin(await GetResolverAsync(Log));
            var ev     = new PersistentEvent {
                Geo = GREEN_BAY_COORDINATES
            };
            await plugin.EventBatchProcessingAsync(new List <EventContext> {
                new EventContext(ev, OrganizationData.GenerateSampleOrganization(), ProjectData.GenerateSampleProject())
            });

            Assert.Equal(GREEN_BAY_COORDINATES, ev.Geo);
            Assert.Null(ev.GetLocation());
        }
示例#10
0
    public async Task AddManualStackSignatureData(string stackingKey, bool willAddManualStackSignature)
    {
        var ev = new PersistentEvent();

        ev.SetManualStackingKey(stackingKey);

        var context = new EventContext(ev, OrganizationData.GenerateSampleOrganization(GetService <BillingManager>(), GetService <BillingPlans>()), ProjectData.GenerateSampleProject());
        var plugin  = GetService <ManualStackingPlugin>();
        await plugin.EventBatchProcessingAsync(new List <EventContext> {
            context
        });

        Assert.Equal(willAddManualStackSignature, context.StackSignatureData.Count > 0);
    }
示例#11
0
        public async Task WillResetLocation(string geo)
        {
            var plugin = new GeoPlugin(await GetResolverAsync(Log));

            var ev = new PersistentEvent {
                Geo = geo
            };
            await plugin.EventBatchProcessingAsync(new List <EventContext> {
                new EventContext(ev, OrganizationData.GenerateSampleOrganization(), ProjectData.GenerateSampleProject())
            });

            Assert.Null(ev.Geo);
            Assert.Null(ev.GetLocation());
        }
示例#12
0
        public async Task SendOrganizationInviteAsync() {
            var user = UserData.GenerateSampleUser();
            var organization = OrganizationData.GenerateSampleOrganization(_billingManager, _plans);

            await _mailer.SendOrganizationInviteAsync(user, organization, new Invite {
                DateAdded = SystemClock.UtcNow,
                EmailAddress = _options.EmailOptions.TestEmailAddress,
                Token = "1"
            });

            await RunMailJobAsync();

            if (GetService<IMailSender>() is InMemoryMailSender sender)
                Assert.Contains("Join Organization", sender.LastMessage.Body);
        }
示例#13
0
        protected void CreateData(int eventCount = 100)
        {
            var org = OrganizationData.GenerateSampleOrganization();

            _organizationRepository.Add(org);

            var projects = ProjectData.GenerateSampleProjects();

            _projectRepository.Add(projects);

            var events = EventData.GenerateEvents(eventCount, projectIds: projects.Select(p => p.Id).ToArray(), startDate: DateTime.Now.SubtractDays(60), endDate: DateTime.Now);

            foreach (var ev in events)
            {
                _eventPipeline.Run(ev);
            }
        }
示例#14
0
        protected void CreateData(int eventCount = 100, bool multipleProjects = true)
        {
            var org = OrganizationData.GenerateSampleOrganization();

            _organizationRepository.Add(org);

            var projects = ProjectData.GenerateSampleProjects();

            _projectRepository.Add(projects);

            var events = EventData.GenerateEvents(eventCount, projectIds: multipleProjects ? projects.Select(p => p.Id).ToArray() : new[] { TestConstants.ProjectId }, startDate: DateTimeOffset.Now.SubtractDays(60), endDate: DateTimeOffset.Now);

            foreach (var ev in events)
            {
                _eventPipeline.Run(ev);
            }
        }
示例#15
0
        public async Task SendInviteAsync()
        {
            User         user         = UserData.GenerateSampleUser();
            Organization organization = OrganizationData.GenerateSampleOrganization();
            await _mailer.SendInviteAsync(user, organization, new Invite {
                DateAdded    = DateTime.Now,
                EmailAddress = Settings.Current.TestEmailAddress,
                Token        = "1"
            });

            await RunMailJobAsync();

            if (_mailSender != null)
            {
                Assert.Equal(Settings.Current.TestEmailAddress, _mailSender.LastMessage.To);
                Assert.Contains("Join Organization", _mailSender.LastMessage.HtmlBody);
            }
        }
示例#16
0
        public async Task WillSetLocationFromGeo()
        {
            var plugin = new GeoPlugin(await GetResolverAsync(Log));
            var ev     = new PersistentEvent {
                Geo = GREEN_BAY_IP
            };
            await plugin.EventBatchProcessingAsync(new List <EventContext> {
                new EventContext(ev, OrganizationData.GenerateSampleOrganization(), ProjectData.GenerateSampleProject())
            });

            Assert.NotNull(ev.Geo);
            Assert.NotEqual(GREEN_BAY_IP, ev.Geo);

            var location = ev.GetLocation();

            Assert.Equal("US", location?.Country);
            Assert.Equal("WI", location?.Level1);
            Assert.Equal("Green Bay", location?.Locality);
        }
示例#17
0
    public async Task SendOrganizationInviteAsync()
    {
        var user         = UserData.GenerateSampleUser();
        var organization = OrganizationData.GenerateSampleOrganization(_billingManager, _plans);

        await _mailer.SendOrganizationInviteAsync(user, organization, new Invite {
            DateAdded    = SystemClock.UtcNow,
            EmailAddress = "*****@*****.**",
            Token        = "1"
        });

        await RunMailJobAsync();

        var sender = GetService <IMailSender>() as InMemoryMailSender;

        Assert.NotNull(sender);

        Assert.Contains("Join Organization", sender.LastMessage.Body);
    }
示例#18
0
        public async Task WillNotCloseDuplicateIdentitySessionsWithSessionIdHeartbeat()
        {
            const string userId    = "*****@*****.**";
            const string sessionId = "123456789";
            var          event1    = GenerateEvent(SystemClock.OffsetNow.SubtractMinutes(5), userId);
            var          event2    = GenerateEvent(SystemClock.OffsetNow.SubtractMinutes(5), userId, sessionId: sessionId);

            var contexts = await _pipeline.RunAsync(new[] { event1, event2 }, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject());

            Assert.True(contexts.All(c => !c.HasError));
            Assert.True(contexts.All(c => !c.IsCancelled));
            Assert.True(contexts.All(c => c.IsProcessed));

            await _configuration.Client.RefreshAsync(Indices.All);

            var events = await _eventRepository.GetAllAsync();

            Assert.Equal(4, events.Total);
            Assert.Equal(2, events.Documents.Where(e => !String.IsNullOrEmpty(e.GetSessionId())).Select(e => e.GetSessionId()).Distinct().Count());
            var sessionStarts = events.Documents.Where(e => e.IsSessionStart()).ToList();

            Assert.Equal(0, sessionStarts.Sum(e => e.Value));
            Assert.DoesNotContain(sessionStarts, e => e.HasSessionEndTime());

            var utcNow = SystemClock.UtcNow;
            await _cache.SetAsync($"Project:{sessionStarts.First().ProjectId}:heartbeat:{userId.ToSHA1()}", utcNow.SubtractMinutes(1));

            await _cache.SetAsync($"Project:{sessionStarts.First().ProjectId}:heartbeat:{sessionId.ToSHA1()}", utcNow.SubtractMinutes(1));

            _job.DefaultInactivePeriod = TimeSpan.FromMinutes(3);
            Assert.Equal(JobResult.Success, await _job.RunAsync());
            await _configuration.Client.RefreshAsync(Indices.All);

            events = await _eventRepository.GetAllAsync();

            Assert.Equal(4, events.Total);

            sessionStarts = events.Documents.Where(e => e.IsSessionStart()).ToList();
            Assert.Equal(2, sessionStarts.Count);
            Assert.Equal(2, sessionStarts.Count(e => !e.HasSessionEndTime()));
            Assert.Equal(0, sessionStarts.Count(e => e.HasSessionEndTime()));
        }
示例#19
0
        public async Task SendInviteAsync()
        {
            User         user         = UserData.GenerateSampleUser();
            Organization organization = OrganizationData.GenerateSampleOrganization();
            await _mailer.SendInviteAsync(user, organization, new Invite {
                DateAdded    = SystemClock.UtcNow,
                EmailAddress = Settings.Current.TestEmailAddress,
                Token        = "1"
            });

            await RunMailJobAsync();

            var sender = GetService <IMailSender>() as InMemoryMailSender;

            if (sender != null)
            {
                Assert.Equal(Settings.Current.TestEmailAddress, sender.LastMessage.To);
                Assert.Contains("Join Organization", sender.LastMessage.HtmlBody);
            }
        }
    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()));
    }
示例#21
0
        public async Task WillResetLocation(string geo)
        {
            var resolver = await GetResolverAsync(Log);

            if (resolver is NullGeoIpService)
            {
                return;
            }

            var plugin = new GeoPlugin(resolver, _options);
            var ev     = new PersistentEvent {
                Geo = geo
            };
            await plugin.EventBatchProcessingAsync(new List <EventContext> {
                new EventContext(ev, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject())
            });

            Assert.Null(ev.Geo);
            Assert.Null(ev.GetLocation());
        }
示例#22
0
        public async Task WillSetLocationFromEnvironmentInfoInfo()
        {
            var plugin = new GeoPlugin(await GetResolverAsync(Log), _options);
            var ev     = new PersistentEvent();

            ev.SetEnvironmentInfo(new EnvironmentInfo {
                IpAddress = $"127.0.0.1,{GREEN_BAY_IP}"
            });
            await plugin.EventBatchProcessingAsync(new List <EventContext> {
                new EventContext(ev, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject())
            });

            Assert.NotNull(ev.Geo);

            var location = ev.GetLocation();

            Assert.Equal("US", location?.Country);
            Assert.Equal("WI", location?.Level1);
            Assert.Equal("Green Bay", location?.Locality);
        }
示例#23
0
        public async Task WillSetMultipleFromEmptyGeo()
        {
            var resolver = await GetResolverAsync(Log);

            if (resolver is NullGeoIpService)
            {
                return;
            }

            var plugin = new GeoPlugin(resolver, _options);

            var ev            = new PersistentEvent();
            var greenBayEvent = new PersistentEvent();

            greenBayEvent.SetEnvironmentInfo(new EnvironmentInfo {
                IpAddress = GREEN_BAY_IP
            });
            var irvingEvent = new PersistentEvent();

            irvingEvent.SetEnvironmentInfo(new EnvironmentInfo {
                IpAddress = IRVING_IP
            });
            await plugin.EventBatchProcessingAsync(new List <EventContext> {
                new EventContext(ev, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject()),
                new EventContext(greenBayEvent, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject()),
                new EventContext(irvingEvent, OrganizationData.GenerateSampleOrganization(_billingManager, _plans), ProjectData.GenerateSampleProject())
            });

            AssertCoordinatesAreEqual(GREEN_BAY_COORDINATES, greenBayEvent.Geo);
            var location = greenBayEvent.GetLocation();

            Assert.Equal("US", location?.Country);
            Assert.Equal("WI", location?.Level1);
            Assert.Equal("Green Bay", location?.Locality);

            AssertCoordinatesAreEqual(IRVING_COORDINATES, irvingEvent.Geo);
            location = irvingEvent.GetLocation();
            Assert.Equal("US", location?.Country);
            Assert.Equal("TX", location?.Level1);
            Assert.Equal("Irving", location?.Locality);
        }
    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()));
    }
示例#25
0
        public async Task SendInviteAsync()
        {
            var mailer       = IoC.GetInstance <Mailer>();
            var mailerSender = IoC.GetInstance <IMailSender>() as InMemoryMailSender;
            var mailJob      = IoC.GetInstance <MailMessageJob>();

            Assert.NotNull(mailerSender);

            User         user         = UserData.GenerateSampleUser();
            Organization organization = OrganizationData.GenerateSampleOrganization();
            await mailer.SendInviteAsync(user, organization, new Invite {
                DateAdded    = DateTime.Now,
                EmailAddress = Settings.Current.TestEmailAddress,
                Token        = "1"
            });

            await mailJob.RunAsync();

            Assert.Equal(1, mailerSender.TotalSent);
            Assert.Equal(Settings.Current.TestEmailAddress, mailerSender.LastMessage.To);
            Assert.Contains("Join Organization", mailerSender.LastMessage.HtmlBody);
        }
示例#26
0
        public async Task CanGetEventTermStatsByTagAsync()
        {
            // capture start date before generating data to make sure that our time range for stats includes all items
            var       startDate  = SystemClock.UtcNow.SubtractDays(60);
            const int eventCount = 100;

            await CreateDataAsync(eventCount, false);

            Log.MinimumLevel = LogLevel.Trace;
            var fields = FieldAggregationProcessor.Process("term:is_first_occurrence:-F", false);

            Assert.True(fields.IsValid);

            var sf     = new ExceptionlessSystemFilterQuery(ProjectData.GenerateSampleProject(), OrganizationData.GenerateSampleOrganization());
            var result = await _stats.GetNumbersTermsStatsAsync("tags", fields.Aggregations, startDate, SystemClock.UtcNow, sf, "fixed:false");

            Assert.Equal(eventCount, result.Total);
            // each event can be in multiple tag buckets since an event can have up to 3 sample tags
            Assert.InRange(result.Terms.Sum(t => t.Total), eventCount, eventCount * 3);
            Assert.InRange(result.Terms.Sum(t => t.Numbers[0]), 1, 25 * TestConstants.EventTags.Count); // new
            Assert.InRange(result.Terms.Count, 1, TestConstants.EventTags.Count);
            foreach (var term in result.Terms)
            {
                Assert.InRange(term.Numbers[0], 1, 25); // new
            }
        }
示例#27
0
        public async Task CanGetEventTermStatsByStackAsync()
        {
            // capture start date before generating data to make sure that our time range for stats includes all items
            var       startDate  = SystemClock.UtcNow.SubtractDays(60);
            const int eventCount = 100;

            await CreateDataAsync(eventCount, false);

            var fields = FieldAggregationProcessor.Process("distinct:stack_id,term:is_first_occurrence:-F", false);

            Assert.True(fields.IsValid);

            var sf     = new ExceptionlessSystemFilterQuery(ProjectData.GenerateSampleProject(), OrganizationData.GenerateSampleOrganization());
            var result = await _stats.GetNumbersTermsStatsAsync("stack_id", fields.Aggregations, startDate, SystemClock.UtcNow, sf);

            Assert.Equal(eventCount, result.Total);
            Assert.InRange(result.Terms.Count, 1, 25);
            // TODO: Figure out why this is less than eventCount
            Assert.Equal(eventCount, result.Terms.Sum(t => t.Total));
            Assert.InRange(result.Terms.Sum(t => t.Numbers[1]), 1, 25); // new
            foreach (var term in result.Terms)
            {
                Assert.Equal(1, term.Numbers[0]); //unique
                Assert.Equal(1, term.Numbers[1]); // new
            }
        }