Beispiel #1
0
        public async Task AbstainAsync(
            [Summary("The ID value of the campaign to be commented upon")]
            long campaignId,
            [Remainder]
            [Summary("The content of the comment")]
            string content)
        {
            await PromotionsService.AddCommentAsync(campaignId, PromotionSentiment.Abstain, content);

            await Context.AddConfirmation();
        }
        public async Task GetTheCountOfPromotionsForTheLastTenDaysAsync_WithValidData_ShouldReturnCorrectCollectionLength()
        {
            //Arrange
            var expectedLength = 10;

            var moqAdsService = new Mock <IAdsService>();
            var context       = InitializeContext.CreateContextForInMemory();

            promotionsService = new PromotionsService(context, moqAdsService.Object);

            //Act
            var actual = await promotionsService.GetTheCountOfPromotionsForTheLastTenDaysAsync();

            //Assert
            Assert.Equal(expectedLength, actual.Count);
        }
        public async Task GetPromotionBindingModelByAdIdAsync_WithInvalidAdId_ShouldThrowAnArgumentException()
        {
            //Arrange
            var expectedErrorMessage = "Ad with the given id doesn't exist!";

            var moqAdsService = new Mock <IAdsService>();
            var context       = InitializeContext.CreateContextForInMemory();

            promotionsService = new PromotionsService(context, moqAdsService.Object);

            //Act and assert
            var ex = await Assert.ThrowsAsync <ArgumentException>(() =>
                                                                  promotionsService.GetPromotionBindingModelByAdIdAsync(1));

            Assert.Equal(expectedErrorMessage, ex.Message);
        }
        public async Task CreatePromotionOrderAsync_WithInvalidPromotionId_ShouldThrowAnArgumentException()
        {
            //Arrange
            var expectedErrorMessage = "Promotion with the given id doesn't exist!";

            var moqAdsService = new Mock <IAdsService>();
            var context       = InitializeContext.CreateContextForInMemory();

            promotionsService = new PromotionsService(context, moqAdsService.Object);

            var testingAd = new Ad
            {
                Id                = 1,
                Title             = "Iphone 6s",
                Description       = "PerfectCondition",
                ActiveFrom        = DateTime.UtcNow,
                ActiveTo          = DateTime.UtcNow.AddDays(30),
                AvailabilityCount = 1,
                Price             = 120,
                Condition         = new Condition {
                    Name = "Brand New"
                },
                Address = new Address
                {
                    Id           = 1,
                    Country      = "Bulgaria",
                    City         = "Sofia",
                    Street       = "Ivan Vazov",
                    District     = "Student city",
                    ZipCode      = 1000,
                    PhoneNumber  = "0895335532",
                    EmailAddress = "*****@*****.**"
                }
            };
            await context.Ads.AddAsync(testingAd);

            await context.SaveChangesAsync();

            //Act and assert
            var ex = await Assert.ThrowsAsync <ArgumentException>(() =>
                                                                  promotionsService.CreatePromotionOrderAsync(1, 1));

            Assert.Equal(expectedErrorMessage, ex.Message);
        }
Beispiel #5
0
        public async Task CampaignsAsync()
        {
            var campaigns = await PromotionsService.SearchCampaignsAsync(new PromotionCampaignSearchCriteria()
            {
                GuildId  = Context.Guild.Id,
                IsClosed = false
            });

            // https://mod.gg/promotions
            var url = new UriBuilder(Config.WebsiteBaseUrl)
            {
                Path = "/promotions"
            }.RemoveDefaultPort().ToString();

            var embed = new EmbedBuilder()
            {
                Title       = Format.Bold("Active Promotion Campaigns"),
                Url         = url,
                Color       = Color.Gold,
                Timestamp   = DateTimeOffset.Now,
                Description = campaigns.Any() ? null : "There are no active promotion campaigns."
            };

            foreach (var campaign in campaigns)
            {
                var idLabel    = $"#{campaign.Id}";
                var votesLabel = (campaign.GetTotalVotes() == 1) ? "Vote" : "Votes";

                var approvalLabel      = $"👍 {campaign.GetNumberOfApprovals()} / 👎 {campaign.GetNumberOfOppositions()}";
                var timeRemaining      = campaign.GetTimeUntilCampaignCanBeClosed();
                var timeRemainingLabel = timeRemaining < TimeSpan.FromSeconds(1) ? "Can be closed now" : $"{timeRemaining.Humanize(precision: 2, minUnit: TimeUnit.Minute)} until close";

                embed.AddField(new EmbedFieldBuilder()
                {
                    Name     = $"{Format.Bold(idLabel)}: {Format.Bold(campaign.Subject.GetFullUsername())} to {campaign.TargetRole.Name}",
                    Value    = $"{approvalLabel} ({timeRemainingLabel})",
                    IsInline = false
                });
            }

            await ReplyAsync("", embed : embed.Build());
        }
Beispiel #6
0
        public async Task Campaigns()
        {
            var campaigns = await PromotionsService.SearchCampaignsAsync(new PromotionCampaignSearchCriteria()
            {
                GuildId  = Context.Guild.Id,
                IsClosed = false
            });

            var embed = new EmbedBuilder()
            {
                Title       = Format.Bold("Active Promotion Campaigns"),
                Url         = "https://mod.gg/promotions",
                Color       = Color.Gold,
                Timestamp   = DateTimeOffset.Now,
                Description = campaigns.Any() ? null : "There are no active promotion campaigns."
            };

            foreach (var campaign in campaigns)
            {
                var totalVotes = campaign.CommentCounts
                                 .Select(x => x.Value)
                                 .Sum();
                var totalApprovals = campaign.CommentCounts
                                     .Where(x => x.Key == PromotionSentiment.Approve)
                                     .Select(x => x.Value)
                                     .Sum();
                var approvalPercentage = Math.Round((float)totalApprovals / totalVotes * 100);

                var idLabel       = $"#{campaign.Id}";
                var votesLabel    = (totalVotes == 1) ? "Vote" : "Votes";
                var approvalLabel = Format.Italics($"{approvalPercentage}% approval");

                embed.AddField(new EmbedFieldBuilder()
                {
                    Name     = $"{Format.Bold(idLabel)}: For {Format.Bold(campaign.Subject.DisplayName)} to {Format.Bold(campaign.TargetRole.Name)}",
                    Value    = $"{totalVotes} {votesLabel} ({approvalLabel})",
                    IsInline = false
                });
            }

            await ReplyAsync("", embed : embed.Build());
        }
Beispiel #7
0
        public async Task CampaignsAsync()
        {
            var campaigns = await PromotionsService.SearchCampaignsAsync(new PromotionCampaignSearchCriteria()
            {
                GuildId  = Context.Guild.Id,
                IsClosed = false
            });

            // https://mod.gg/promotions
            var url = new UriBuilder(Config.WebsiteBaseUrl)
            {
                Path = "/promotions"
            }.RemoveDefaultPort().ToString();

            var embed = new EmbedBuilder()
            {
                Title       = Format.Bold("Active Promotion Campaigns"),
                Url         = url,
                Color       = Color.Gold,
                Timestamp   = DateTimeOffset.Now,
                Description = campaigns.Any() ? null : "There are no active promotion campaigns."
            };

            foreach (var campaign in campaigns)
            {
                var idLabel    = $"#{campaign.Id}";
                var votesLabel = (campaign.GetTotalVotes() == 1) ? "Vote" : "Votes";

                var percentage    = Math.Round(campaign.GetApprovalPercentage() * 100);
                var approvalLabel = Format.Italics($"{percentage}% approval");

                embed.AddField(new EmbedFieldBuilder()
                {
                    Name     = $"{Format.Bold(idLabel)}: For {Format.Bold(campaign.Subject.GetFullUsername())} to {Format.Bold(campaign.TargetRole.Name)}",
                    Value    = $"{campaign.GetTotalVotes()} {votesLabel} ({approvalLabel})",
                    IsInline = false
                });
            }

            await ReplyAsync("", embed : embed.Build());
        }
Beispiel #8
0
        public async Task OnPromotionActionCreatedAsync(long moderationActionId, PromotionActionCreationData data)
        {
            if (!await DesignatedChannelService.AnyDesignatedChannelAsync(data.GuildId, DesignatedChannelType.PromotionLog))
            {
                return;
            }

            try
            {
                var promotionAction = await PromotionsService.GetPromotionActionSummaryAsync(moderationActionId);

                if (!_renderTemplates.TryGetValue((promotionAction.Type, promotionAction.Comment?.Sentiment, promotionAction.Campaign?.Outcome), out var renderTemplate))
                {
                    return;
                }

                var message = string.Format(renderTemplate,
                                            promotionAction.Created.UtcDateTime.ToString("HH:mm:ss"),
                                            promotionAction.Campaign?.Id,
                                            promotionAction.Campaign?.Subject.DisplayName,
                                            promotionAction.Campaign?.Subject.Id,
                                            promotionAction.Campaign?.TargetRole.Name,
                                            promotionAction.Campaign?.TargetRole.Id,
                                            promotionAction.Comment?.Campaign.Id,
                                            promotionAction.Comment?.Campaign.Subject.DisplayName,
                                            promotionAction.Comment?.Campaign.Subject.Id,
                                            promotionAction.Comment?.Campaign.TargetRole.Name,
                                            promotionAction.Comment?.Campaign.TargetRole.Id,
                                            promotionAction.Comment?.Content);

                await DesignatedChannelService.SendToDesignatedChannelsAsync(
                    await DiscordClient.GetGuildAsync(data.GuildId), DesignatedChannelType.PromotionLog, message);
            }
            catch (Exception ex)
            {
                var text = Newtonsoft.Json.JsonConvert.SerializeObject(ex);
            }
        }
        private async Task <string> FormatPromotionLogEntry(long promotionActionId, PromotionActionCreationData data)
        {
            var promotionAction = await PromotionsService.GetPromotionActionSummaryAsync(promotionActionId);

            if (!_logRenderTemplates.TryGetValue((promotionAction.Type, promotionAction.NewComment?.Sentiment, promotionAction.Campaign?.Outcome), out var renderTemplate))
            {
                return(null);
            }

            return(string.Format(renderTemplate,
                                 promotionAction.Created.UtcDateTime.ToString("HH:mm:ss"),
                                 promotionAction.Campaign?.Id,
                                 promotionAction.Campaign?.Subject.DisplayName,
                                 promotionAction.Campaign?.Subject.Id,
                                 promotionAction.Campaign?.TargetRole.Name,
                                 promotionAction.Campaign?.TargetRole.Id,
                                 promotionAction.NewComment?.Campaign.Id,
                                 promotionAction.NewComment?.Campaign.Subject.DisplayName,
                                 promotionAction.NewComment?.Campaign.Subject.Id,
                                 promotionAction.NewComment?.Campaign.TargetRole.Name,
                                 promotionAction.NewComment?.Campaign.TargetRole.Id,
                                 promotionAction.NewComment?.Content));
        }
        private async Task <Embed> FormatPromotionNotificationAsync(long promotionActionId, PromotionActionCreationData data)
        {
            var promotionAction = await PromotionsService.GetPromotionActionSummaryAsync(promotionActionId);

            var targetCampaign = promotionAction.Campaign ?? promotionAction.NewComment.Campaign;

            var embed = new EmbedBuilder();

            if (promotionAction.Type != PromotionActionType.CampaignClosed)
            {
                return(null);
            }
            if (targetCampaign.Outcome != PromotionCampaignOutcome.Accepted)
            {
                return(null);
            }

            var boldName = $"**{targetCampaign.Subject.GetFullUsername()}**";
            var boldRole = $"**{MentionUtils.MentionRole(targetCampaign.TargetRole.Id)}**";

            var subject = await UserService.GetUserInformationAsync(data.GuildId, targetCampaign.Subject.Id);

            // https://modix.gg/promotions
            var url = new UriBuilder(ModixConfig.WebsiteBaseUrl)
            {
                Path = "/promotions"
            }.RemoveDefaultPort().ToString();

            embed = embed
                    .WithTitle("The campaign is over!")
                    .WithDescription($"Staff accepted the campaign, and {boldName} was promoted to {boldRole}! 🎉")
                    .WithUserAsAuthor(subject)
                    .WithFooter($"See more at {url}");

            return(embed.Build());
        }
        public async Task GetPromotionBindingModelByAdIdAsync_WithValidData_ShouldReturnCorrectPromotionBindingModel()
        {
            //Arrange
            var expected = new PromotionBindingModel
            {
                AdId                = 1,
                AdTitle             = "Iphone 6s",
                PromotionViewModels = new List <PromotionViewModel>
                {
                    new PromotionViewModel
                    {
                        ActiveDays = 10,
                        Price      = 3.50M,
                        Type       = "Silver",
                        Updates    = 3
                    },
                    new PromotionViewModel
                    {
                        ActiveDays = 30,
                        Price      = 8.00M,
                        Type       = "Gold",
                        Updates    = 10
                    }
                }
            };

            var moqAdsService = new Mock <IAdsService>();

            moqAdsService.Setup(x => x.GetAdByIdAsync(1))
            .ReturnsAsync(new Ad
            {
                Id                = 1,
                Title             = "Iphone 6s",
                Description       = "PerfectCondition",
                ActiveFrom        = DateTime.UtcNow,
                ActiveTo          = DateTime.UtcNow.AddDays(30),
                AvailabilityCount = 1,
                Price             = 120,
                Condition         = new Condition {
                    Name = "Brand New"
                },
                Address = new Address
                {
                    Country      = "Bulgaria",
                    City         = "Sofia",
                    Street       = "Ivan Vazov",
                    District     = "Student city",
                    ZipCode      = 1000,
                    PhoneNumber  = "0895335532",
                    EmailAddress = "*****@*****.**"
                }
            });

            var context = InitializeContext.CreateContextForInMemory();

            promotionsService = new PromotionsService(context, moqAdsService.Object);
            var testingAd = new Ad
            {
                Id                = 1,
                Title             = "Iphone 6s",
                Description       = "PerfectCondition",
                ActiveFrom        = DateTime.UtcNow,
                ActiveTo          = DateTime.UtcNow.AddDays(30),
                AvailabilityCount = 1,
                Price             = 120,
                Condition         = new Condition {
                    Name = "Brand New"
                },
                Address = new Address
                {
                    Id           = 1,
                    Country      = "Bulgaria",
                    City         = "Sofia",
                    Street       = "Ivan Vazov",
                    District     = "Student city",
                    ZipCode      = 1000,
                    PhoneNumber  = "0895335532",
                    EmailAddress = "*****@*****.**"
                }
            };

            var testingPromotions = new List <Promotion>
            {
                new Promotion
                {
                    ActiveDays = 10,
                    Price      = 3.50M,
                    Type       = "silver",
                    Updates    = 3
                },
                new Promotion
                {
                    ActiveDays = 30,
                    Price      = 8.00M,
                    Type       = "gold",
                    Updates    = 10
                }
            };

            await context.Ads.AddAsync(testingAd);

            await context.Promotions.AddRangeAsync(testingPromotions);

            await context.SaveChangesAsync();

            //Act
            var actual = await promotionsService.GetPromotionBindingModelByAdIdAsync(1);

            Assert.Equal(expected.AdId, actual.AdId);
            Assert.Equal(expected.AdTitle, actual.AdTitle);
            Assert.Collection(actual.PromotionViewModels,
                              elem1 =>
            {
                Assert.Equal(expected.PromotionViewModels[0].ActiveDays, elem1.ActiveDays);
                Assert.Equal(expected.PromotionViewModels[0].Price, elem1.Price);
                Assert.Equal(expected.PromotionViewModels[0].Type, elem1.Type);
                Assert.Equal(expected.PromotionViewModels[0].Updates, elem1.Updates);
            },
                              elem2 =>
            {
                Assert.Equal(expected.PromotionViewModels[1].ActiveDays, elem2.ActiveDays);
                Assert.Equal(expected.PromotionViewModels[1].Price, elem2.Price);
                Assert.Equal(expected.PromotionViewModels[1].Type, elem2.Type);
                Assert.Equal(expected.PromotionViewModels[1].Updates, elem2.Updates);
            });

            Assert.Equal(expected.PromotionViewModels.Count, actual.PromotionViewModels.Count);
        }
Beispiel #12
0
 public Task Approve(
     [Summary("The ID value of the campaign to be commented upon")]
     long campaignId)
 => PromotionsService.AddCommentAsync(campaignId, PromotionSentiment.Approve, DefaultApprovalMessage);
Beispiel #13
0
 public PromotionsServiceUnitTest()
 {
     _promotionsService = new PromotionsService();
 }
Beispiel #14
0
        private async Task <Embed> FormatPromotionNotification(long promotionActionId, PromotionActionCreationData data)
        {
            var promotionAction = await PromotionsService.GetPromotionActionSummaryAsync(promotionActionId);

            var targetCampaign = promotionAction.Campaign ?? promotionAction.NewComment.Campaign;

            var embed = new EmbedBuilder();

            //Because we have comment creation as a separate operation from starting the campaign,
            //we don't have access to the "initial" comment when a campaign is created. So, we have to
            //note that a campaign was created, and actually send the log message when the first comment
            //is created (containing the comment body)
            switch (promotionAction.Type)
            {
            case PromotionActionType.CampaignCreated:

                _initialCommentQueue.TryAdd(targetCampaign.Id, embed
                                            .WithTitle("A new campaign has been started!")
                                            .AddField("If accepted, their new role will be", MentionUtils.MentionRole(targetCampaign.TargetRole.Id)));

                return(null);

            case PromotionActionType.CampaignClosed:

                var fullCampaign = (await PromotionsService.SearchCampaignsAsync(new PromotionCampaignSearchCriteria
                {
                    Id = targetCampaign.Id
                }))
                                   .First();

                embed = embed
                        .WithTitle("The campaign is over!")
                        .AddField("Approval Rate", fullCampaign.GetApprovalPercentage().ToString("p"), true);

                var boldName = $"**{targetCampaign.Subject.Username}#{targetCampaign.Subject.Discriminator}**";
                var boldRole = $"**{MentionUtils.MentionRole(targetCampaign.TargetRole.Id)}**";

                switch (targetCampaign.Outcome)
                {
                case PromotionCampaignOutcome.Accepted:
                    embed = embed
                            .WithDescription($"Staff accepted the campaign, and {boldName} was promoted to {boldRole}! 🎉");
                    break;

                case PromotionCampaignOutcome.Rejected:
                    embed = embed
                            .WithDescription($"Staff rejected the campaign to promote {boldName} to {boldRole}");
                    break;

                case PromotionCampaignOutcome.Failed:
                default:
                    embed = embed
                            .WithDescription("There was an issue while accepting or denying the campaign. Ask staff for details.")
                            .AddField("Target Role", MentionUtils.MentionRole(targetCampaign.TargetRole.Id), true);
                    break;
                }

                break;

            case PromotionActionType.CommentCreated:

                if (_initialCommentQueue.TryRemove(targetCampaign.Id, out embed))
                {
                    embed.Description = $"👍 {promotionAction.NewComment.Content}";
                }
                else
                {
                    return(null);
                }

                break;

            case PromotionActionType.CommentModified:
            default:
                return(null);
            }

            var subject = await UserService.GetUserInformationAsync(data.GuildId, targetCampaign.Subject.Id);

            return(embed
                   .WithAuthor(subject)
                   .WithFooter("See more at https://mod.gg/promotions")
                   .Build());
        }
Beispiel #15
0
 public Task Accept(
     [Summary("The ID value of the campaign to be accepted.")]
     long campaignId,
     [Summary("Whether to bypass the time restriction on campaign acceptance")]
     bool force = false)
 => PromotionsService.AcceptCampaignAsync(campaignId, force);
 public CatalogActivity()
 {
     _mPromotionsService = new PromotionsService();
     _mCategoriesService = new CategoriesService();
     _mProductsService   = new ProductsService();
 }
        public async Task CreatePromotionOrderAsync_WithValidData_ShouldCreateAnPromotionOrder()
        {
            //Arrange
            var moqAdsService = new Mock <IAdsService>();

            moqAdsService.Setup(x => x.GetAdByIdAsync(1))
            .ReturnsAsync(new Ad
            {
                Id                = 1,
                Title             = "Iphone 6s",
                Description       = "PerfectCondition",
                ActiveFrom        = DateTime.UtcNow,
                ActiveTo          = DateTime.UtcNow.AddDays(30),
                AvailabilityCount = 1,
                Price             = 120,
                Condition         = new Condition {
                    Name = "Brand New"
                },
                Address = new Address
                {
                    Country      = "Bulgaria",
                    City         = "Sofia",
                    Street       = "Ivan Vazov",
                    District     = "Student city",
                    ZipCode      = 1000,
                    PhoneNumber  = "0895335532",
                    EmailAddress = "*****@*****.**"
                }
            });

            var context = InitializeContext.CreateContextForInMemory();

            promotionsService = new PromotionsService(context, moqAdsService.Object);

            var testingAd = new Ad
            {
                Id                = 1,
                Title             = "Iphone 6s",
                Description       = "PerfectCondition",
                ActiveFrom        = DateTime.UtcNow,
                ActiveTo          = DateTime.UtcNow.AddDays(30),
                AvailabilityCount = 1,
                Price             = 120,
                Condition         = new Condition {
                    Name = "Brand New"
                },
                Address = new Address
                {
                    Id           = 1,
                    Country      = "Bulgaria",
                    City         = "Sofia",
                    Street       = "Ivan Vazov",
                    District     = "Student city",
                    ZipCode      = 1000,
                    PhoneNumber  = "0895335532",
                    EmailAddress = "*****@*****.**"
                }
            };

            var testingPromotion = new Promotion
            {
                Id         = 1,
                ActiveDays = 10,
                Price      = 3.50M,
                Type       = "silver",
                Updates    = 3
            };

            await context.Ads.AddAsync(testingAd);

            await context.Promotions.AddAsync(testingPromotion);

            await context.SaveChangesAsync();

            //Act
            await promotionsService.CreatePromotionOrderAsync(1, 1);

            //Assert
            Assert.True(context.PromotionOrders.Count() == 1);
        }
Beispiel #18
0
 public Task Reject(
     [Summary("The ID value of the campaign to be rejected.")]
     long campaignId)
 => PromotionsService.RejectCampaignAsync(campaignId);
Beispiel #19
0
 public Task Accept(
     [Summary("The ID value of the campaign to be accepted.")]
     long campaignId)
 => PromotionsService.AcceptCampaignAsync(campaignId);