internal static JobExecutionListResult DeserializeJobExecutionListResult(JsonElement element)
        {
            Optional <IReadOnlyList <JobExecutionData> > value = default;
            Optional <string> nextLink = default;

            foreach (var property in element.EnumerateObject())
            {
                if (property.NameEquals("value"))
                {
                    if (property.Value.ValueKind == JsonValueKind.Null)
                    {
                        property.ThrowNonNullablePropertyIsNull();
                        continue;
                    }
                    List <JobExecutionData> array = new List <JobExecutionData>();
                    foreach (var item in property.Value.EnumerateArray())
                    {
                        array.Add(JobExecutionData.DeserializeJobExecutionData(item));
                    }
                    value = array;
                    continue;
                }
                if (property.NameEquals("nextLink"))
                {
                    nextLink = property.Value.GetString();
                    continue;
                }
            }
            return(new JobExecutionListResult(Optional.ToList(value), nextLink.Value));
        }
        ServerJobAgentJobExecution IOperationSource <ServerJobAgentJobExecution> .CreateResult(Response response, CancellationToken cancellationToken)
        {
            using var document = JsonDocument.Parse(response.ContentStream);
            var data = JobExecutionData.DeserializeJobExecutionData(document.RootElement);

            return(new ServerJobAgentJobExecution(_armClient, data));
        }
        public void TestObserverJobExecution_When_User_Was_Under_Attack_Gameplay_Returns_Attack()
        {
            var villageRepoMock = new Mock <IVillageRepository>();

            villageRepoMock.Setup(x => x.GetVillages(FakeDataProvider.TravianUserName))
            .Returns(Task.FromResult((IEnumerable <VillageModel>)FakeDataProvider.GetVillagesFromDatabase(true)));

            _serviceBuilder = _serviceBuilder
                              .WithService(villageRepoMock.Object);

            var observerJob = new ObserverJob(_serviceBuilder.Build());
            var context     = new Mock <IJobExecutionContext>();
            var jobDetail   = new Mock <IJobDetail>();
            var data        = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK, true)
            };

            jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data);
            context.Setup(x => x.JobDetail).Returns(jobDetail.Object);
            Assert.DoesNotThrowAsync(async() => await observerJob.Execute(data));
            _logger.Verify(x => x.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);
            _cmdFactoryMock.Verify(x => x.GetQueueableCommand(nameof(PrepareToAttackCommand), It.IsAny <long>()), Times.Once);
            _travianUserRepoMock.Verify(x => x.ReplacePlayerDataVillages(It.IsAny <TravianUser>()), Times.Once);

            Assert.AreEqual(2, _reportMsgs.Count);
            Assert.IsTrue(_reportMsgs[1].Contains($"Village [test_village_under_attack] is under attack."));
            Assert.IsTrue(_reportMsgs[1].Contains(FakeDataProvider.NewAttackDateTime.ToDisplayStringApplyTimeZone("UTC+2")));

            Assert.AreEqual(1, _updates.Count);
            Assert.AreEqual(PlayerStatus.UNDER_ATTACK, _updates.First().PlayerData.Status);
        }
Beispiel #4
0
        public static JobKey BuildJobKey(JobExecutionData jobData)
        {
            var additional = string.Empty;

            if (string.IsNullOrEmpty(jobData.Cron))
            {
                additional = $":timestamp:{jobData.Start.ToTimeStamp()}";
            }

            return(new JobKey($"{jobData.JobType.Name}:job:for:{jobData.TravianUser.UserName}{additional}", BuildGroupKey(jobData.TravianUser.UserName, jobData.TravianUser.BotUserName)));
        }
Beispiel #5
0
        public void Test_Prepare_To_Attack()
        {
            var actionProviderMock = new Mock <IActionProvider>();

            actionProviderMock.Setup(x => x.GetActionsForPlayer(It.IsNotNull <TravianUser>()))
            .Returns(Task.FromResult((IEnumerable <GameAction>)Builder <GameAction>
                                     .CreateListOfSize(2)
                                     .TheFirst(1)
                                     .With(x => x.Action  = GameActionType.TRAIN_ARMY)
                                     .With(x => x.Village = Builder <Village> .CreateNew().With(y => y.Name = "test_village_1").Build())
                                     .TheNext(1)
                                     .With(x => x.Action  = GameActionType.SEND_RESOURCES)
                                     .With(x => x.Village = Builder <Village> .CreateNew().With(y => y.Name = "test_village_2").Build())
                                     .Build()));
            var gameplayMock = new Mock <IGameplayClient>();

            gameplayMock
            .Setup(x => x.ExecuteActions(It.IsNotNull <TravianUser>(), It.IsNotNull <List <GameAction> >()))
            .Returns(Task.FromResult(Builder <BaseScenarioResult> .CreateNew().Build()));

            _serviceBuilder = _serviceBuilder
                              .WithService(actionProviderMock.Object)
                              .WithService(gameplayMock.Object);

            var job = new PrepareToAttackJob(_serviceBuilder.Build());
            //var context = new Mock<IJobExecutionContext>();
            //var jobDetail = new Mock<IJobDetail>();
            var data = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK, true),
                JobType     = typeof(PrepareToAttackJob)
            };

            //jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data);
            //context.Setup(x => x.JobDetail).Returns(jobDetail.Object);
            Assert.DoesNotThrowAsync(async() => await job.Execute(data));

            _serviceBuilder.LoggerMock.Verify(x => x.Log(
                                                  LogLevel.Error,
                                                  It.IsAny <EventId>(),
                                                  It.IsAny <It.IsAnyType>(),
                                                  It.IsAny <Exception>(),
                                                  (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);

            Assert.AreEqual(2, _serviceBuilder.Messages.Count);
            Assert.AreEqual($"The village test_village_1 was prepared to attack with following action: [TRAIN_ARMY].", _serviceBuilder.Messages[0]);
            Assert.AreEqual($"The village test_village_2 was prepared to attack with following action: [SEND_RESOURCES].", _serviceBuilder.Messages[1]);
        }
        public void TestObserverJobExecution_When_It_Was_Quiet_And_Gameplay_Returns_Attack()
        {
            var villageRepoMock = new Mock <IVillageRepository>();

            villageRepoMock.Setup(x => x.GetVillages(FakeDataProvider.TravianUserName))
            .Returns(Task.FromResult((IEnumerable <VillageModel>)FakeDataProvider.GetVillagesFromDatabase(false)));

            _serviceBuilder = _serviceBuilder
                              .WithService(villageRepoMock.Object);

            var observerJob = new ObserverJob(_serviceBuilder.Build());
            var context     = new Mock <IJobExecutionContext>();
            var jobDetail   = new Mock <IJobDetail>();
            var data        = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true)
            };

            jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data);
            context.Setup(x => x.JobDetail).Returns(jobDetail.Object);
            Assert.DoesNotThrowAsync(async() => await observerJob.Execute(data));
            _logger.Verify(x => x.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);
            _cmdFactoryMock.Verify(x => x.GetQueueableCommand(nameof(PrepareToAttackCommand), It.IsAny <long>()), Times.Exactly(2));
            _travianUserRepoMock.Verify(x => x.ReplacePlayerDataVillages(It.IsAny <TravianUser>()), Times.Once);

            Assert.AreEqual(7, _reportMsgs.Count);
            Assert.IsTrue(_reportMsgs[0].Contains($"Player {FakeDataProvider.TravianUserName} has been scanned"));
            Assert.IsTrue(_reportMsgs[1].Contains($"Player {FakeDataProvider.TravianUserName} has been scanned"));
            Assert.IsTrue(_reportMsgs[2].Contains($"Player {FakeDataProvider.TravianUserName} is under attack:"));
            Assert.IsTrue(_reportMsgs[2].Contains("The village [test_village_under_attack] is under attack"));
            Assert.IsTrue(_reportMsgs[3].Contains($"Player {FakeDataProvider.TravianUserName} is under attack:"));
            Assert.IsTrue(_reportMsgs[3].Contains("The village [test_village_under_attack] is under attack"));
            Assert.AreEqual(_reportMsgs[4], $"New incoming attacks discovered for player [{FakeDataProvider.TravianUserName}]");
            Assert.IsTrue(_reportMsgs[5].Contains($"Village [{FakeDataProvider.TestVillageName}] is under attack"));
            Assert.IsTrue(_reportMsgs[5].Contains($"The attack date time:"));
            Assert.IsTrue(_reportMsgs[5].Contains($"The intruder:"));
            Assert.IsTrue(_reportMsgs[6].Contains($"Village [{FakeDataProvider.TestVillageName}] is under attack"));
            Assert.IsTrue(_reportMsgs[6].Contains($"The attack date time:"));
            Assert.IsTrue(_reportMsgs[6].Contains($"The intruder:"));

            Assert.AreEqual(2, _updates.Count);
            Assert.AreEqual(PlayerStatus.UNDER_ATTACK, _updates.First().PlayerData.Status);
        }
Beispiel #7
0
        public async Task Execute(string parameters = "")
        {
            var jobData = new JobExecutionData
            {
                Cron    = Cron,
                JobType = JobType
            };

            IJobDetail job = JobBuilder.Create(typeof(EmptyJob))
                             .WithIdentity($"{Name}_{JobType}")
                             .Build();

            job.JobDataMap[AbstractJob.JobExecutionDataKey] = jobData;

            var trigger = TriggerBuilder.Create()
                          .WithIdentity($"{jobData.JobType.Name}:trigger", $"{jobData.JobType.Name}")
                          .WithCronSchedule(jobData.Cron).Build();

            await _scheduler.ScheduleJob(job, trigger, new System.Threading.CancellationToken());
        }
        public void TestObserverJobExecution_When_User_Was_Under_Attack_Gameplay_Returns_All_Quiet()
        {
            var villageRepoMock = new Mock <IVillageRepository>();

            villageRepoMock.Setup(x => x.GetVillages(FakeDataProvider.TravianUserName))
            .Returns(Task.FromResult((IEnumerable <VillageModel>)FakeDataProvider.GetVillagesFromDatabase(false)));

            var user   = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK);
            var result = Builder <BaseScenarioResult>
                         .CreateNew()
                         .With(x => x.Villages = Builder <Village> .CreateListOfSize(2).All().With(y => y.Attacks = null).Build().ToList())
                         .Build();

            var gameplayMock = new Mock <IGameplayClient>();

            gameplayMock.Setup(x => x.RunScan(It.IsAny <TravianUser>(), It.IsAny <bool>())).Returns(Task.FromResult(result));

            _serviceBuilder = _serviceBuilder
                              .WithService(villageRepoMock.Object)
                              .WithService(gameplayMock.Object);

            var observerJob = new ObserverJob(_serviceBuilder.Build());
            var context     = new Mock <IJobExecutionContext>();
            var jobDetail   = new Mock <IJobDetail>();
            var data        = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.UNDER_ATTACK, true)
            };

            jobDetail.Setup(x => x.JobDataMap[AbstractJob.JobExecutionDataKey]).Returns(data);
            context.Setup(x => x.JobDetail).Returns(jobDetail.Object);
            Assert.DoesNotThrowAsync(async() => await observerJob.Execute(data));
            _logger.Verify(x => x.Log(LogLevel.Error, It.IsAny <EventId>(), It.IsAny <It.IsAnyType>(), It.IsAny <Exception>(), (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);
            _travianUserRepoMock.Verify(x => x.ReplacePlayerDataVillages(It.IsAny <TravianUser>()), Times.Once);
            _travianUserRepoMock.Verify(x => x.ReplacePlayerData(It.IsAny <TravianUser>()), Times.Once);
            _travianUserRepoMock.Verify(x => x.ReplacePlayerData(It.IsAny <TravianUser>()), Times.Once);

            Assert.AreEqual(2, _updates.Count);
            Assert.AreEqual(PlayerStatus.ALL_QUIET, _updates.First().PlayerData.Status);
        }
Beispiel #9
0
        public async Task <JobKey> ScheduleCommandAsync(JobExecutionData jobData, CancellationToken cancellationToken)
        {
            try
            {
                if (string.IsNullOrEmpty(jobData.JobType.Name))
                {
                    throw new ArgumentNullException(nameof(jobData.JobType.Name), "The command name must be specified.");
                }

                IJobDetail job = JobBuilder.Create(typeof(MasterJob))
                                 .WithIdentity(BuildJobKey(jobData))
                                 .Build();

                job.JobDataMap[AbstractJob.JobExecutionDataKey] = jobData;

                var builder = TriggerBuilder.Create()
                              .WithIdentity($"{jobData.JobType.Name}:trigger:for:{jobData.TravianUser.UserName}:timestamp:{jobData.Start.ToTimeStamp()}", $"{jobData.TravianUser.BotUserName}.group")
                              .WithDescription($"{jobData.JobType}.trigger.With: CRON: {jobData.Cron}, StartDateTime: {jobData.Start.ToFormattedStringWithMills()}")
                              .StartAt(jobData.Start);

                var trigger = string.IsNullOrEmpty(jobData.Cron)
                    ? builder.Build()
                    : builder.WithCronSchedule(jobData.Cron).Build();

                await _scheduler.ScheduleJob(job, trigger, cancellationToken);

                if (!string.IsNullOrEmpty(jobData.Cron) || jobData.Start < DateTimeOffset.UtcNow && (DateTimeOffset.UtcNow - jobData.Start).TotalMinutes < 5)
                {
                    await _scheduler.TriggerJob(job.Key);
                }

                return(job.Key);
            }
            catch (Exception exc)
            {
                this._logger.LogError(LoggingEvents.BackgroundJobCreationException, exc, $"Unable to create new Job instance of type [{jobData.JobType}]");
                return(null);
            }
        }
        public void Test_One_Village_With_Building_Being_Built()
        {
            var testVillage   = PrepareTestOneVillage();
            var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage);
            var finishTime    = TimeSpan.FromMinutes(30);

            resultVillage.Dorf1BuildTimeLeft = finishTime;
            resultVillage.CanBuild           = false;
            resultVillage.Resources          = new Resources
            {
                Lumber = 100,
                Clay   = 100,
                Iron   = 100,
                Crop   = 100
            };
            resultVillage.Warehourse = 800;
            resultVillage.Granary    = 800;

            var infoResult = Builder <BaseScenarioResult> .CreateNew()
                             .With(x => x.Success  = true)
                             .With(x => x.Villages = new List <Village> {
                resultVillage
            })
                             .Build();

            var gamePlayMock = new Mock <IGameplayClient>();

            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()))
            .Returns(Task.FromResult(infoResult));
            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()))
            .Returns(Task.FromResult(new BaseScenarioResult()));
            _serviceProviderBuilder.WithService(gamePlayMock.Object);

            var cmd     = new FakeCommand();
            var cmdMock = new Mock <ICommandFactory>();

            cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>()))
            .Returns(cmd);

            _serviceProviderBuilder.WithService(cmdMock.Object);

            var job  = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build());
            var data = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true),
                JobType     = typeof(BuildingPlanExecutionJob)
            };

            var now = DateTimeOffset.Now;

            Assert.DoesNotThrowAsync(async() => await job.Execute(data));

            _serviceProviderBuilder.LoggerMock.Verify(x => x.Log(
                                                          LogLevel.Error,
                                                          It.IsAny <EventId>(),
                                                          It.IsAny <It.IsAnyType>(),
                                                          It.IsAny <Exception>(),
                                                          (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);
            gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()), Times.Once);
            gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Never);

            var diff = cmd.Start - now - finishTime;

            Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now
            Assert.IsTrue(diff >= TimeSpan.FromSeconds(2));
        }
        private AbstractJob PrepareOneVillageTest(BaseScenarioResult buildScenarioResult, BaseScenarioResult infoScenarioResult)
        {
            var testVillage   = PrepareTestOneVillage(isBuildingFeatureOn: true);
            var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage);
            var finishTime    = TimeSpan.FromMinutes(30);

            resultVillage.Dorf1BuildTimeLeft = finishTime;
            resultVillage.CanBuild           = true;
            resultVillage.Resources          = new Resources
            {
                Lumber = 100,
                Clay   = 100,
                Iron   = 100,
                Crop   = 100
            };
            resultVillage.Warehourse = 800;
            resultVillage.Granary    = 800;

            var infoResult = Builder <BaseScenarioResult> .CreateNew()
                             .With(x => x.Success  = true)
                             .With(x => x.Villages = new List <Village> {
                resultVillage
            })
                             .Build();

            var actionProviderMock = new Mock <IActionProvider>();

            actionProviderMock.Setup(x => x.GetBuildActions(resultVillage, It.IsAny <IEnumerable <BuildingModel> >()))
            .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> {
                new BuildAction
                {
                    Village = resultVillage,
                    BuildingId = "test",
                    BuildingSlot = "test",
                    Level = 1
                }
            })));
            _serviceProviderBuilder.WithService(actionProviderMock.Object);

            var buildActionResult = Builder <BaseScenarioResult> .CreateNew()
                                    .With(x => x.Success  = true)
                                    .With(x => x.Villages = new List <Village>
            {
                Builder <Village>
                .CreateNew()
                .With(y => y.CanBuild           = false)
                .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5))
                .Build()
            })
                                    .Build();

            var gamePlayMock = new Mock <IGameplayClient>();

            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()))
            .Returns(Task.FromResult(infoResult));
            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()))
            .Returns(Task.FromResult(buildActionResult));
            _serviceProviderBuilder.WithService(gamePlayMock.Object);

            var cmd     = new FakeCommand();
            var cmdMock = new Mock <ICommandFactory>();

            cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>()))
            .Returns(cmd);
            _serviceProviderBuilder.WithService(cmdMock.Object);

            var job  = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build());
            var data = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true),
                JobType     = typeof(BuildingPlanExecutionJob)
            };

            return(job);
        }
        public async Task Test_Three_Villages_Build_Action_Returns_Error(BuildErrorType errorType)
        {
            var testVillage   = GetVillage(isBuildingFeatureOn: true);
            var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage);
            var finishTime    = TimeSpan.FromMinutes(30);

            resultVillage.Dorf1BuildTimeLeft = finishTime;
            resultVillage.CanBuild           = true;
            resultVillage.Resources          = new Resources
            {
                Lumber = 100,
                Clay   = 100,
                Iron   = 100,
                Crop   = 100
            };
            resultVillage.Warehourse = 800;
            resultVillage.Granary    = 800;

            var testVillage2   = GetVillage(isBuildingFeatureOn: true);
            var resultVillage2 = _serviceProviderBuilder.Mapper.Map <Village>(testVillage2);
            var finishTime2    = TimeSpan.FromMinutes(45);

            resultVillage2.Dorf1BuildTimeLeft = finishTime2;
            resultVillage2.CanBuild           = true;
            resultVillage2.Resources          = new Resources
            {
                Lumber = 100,
                Clay   = 100,
                Iron   = 100,
                Crop   = 100
            };
            resultVillage2.Warehourse = 800;
            resultVillage2.Granary    = 800;

            var testVillage3 = GetVillage(isBuildingFeatureOn: false);

            resultVillage2.Resources = new Resources
            {
                Lumber = 100,
                Clay   = 100,
                Iron   = 100,
                Crop   = 100
            };
            resultVillage2.Warehourse = 800;
            resultVillage2.Granary    = 800;

            var allVillages = new List <VillageModel> {
                testVillage, testVillage2, testVillage3
            };
            var villageRepo = new Mock <IVillageRepository>();

            villageRepo.Setup(x => x.GetVillages(_serviceProviderBuilder.TravianUser.UserName))
            .Returns(Task.FromResult((IEnumerable <VillageModel>)allVillages));
            villageRepo.Setup(x => x.GetVillage(It.IsAny <int>(), It.IsAny <int>()))
            .Returns((int x, int y) =>
            {
                return(Task.FromResult(allVillages.FirstOrDefault(z => z.CoordinateX == x && z.CoordinateY == y)));
            });
            _serviceProviderBuilder.WithService(villageRepo.Object);

            var infoResult = Builder <BaseScenarioResult> .CreateNew()
                             .With(x => x.Success  = true)
                             .With(x => x.Villages = new List <Village> {
                resultVillage2
            })
                             .Build();

            var actionProviderMock = new Mock <IActionProvider>();

            actionProviderMock.Setup(x => x.GetBuildActions(resultVillage, It.IsAny <IEnumerable <BuildingModel> >()))
            .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> {
                new BuildAction
                {
                    Village = resultVillage,
                    BuildingId = "test",
                    BuildingSlot = "test",
                    Level = 1
                }
            })));
            actionProviderMock.Setup(x => x.GetBuildActions(resultVillage2, It.IsAny <IEnumerable <BuildingModel> >()))
            .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> {
                new BuildAction
                {
                    Village = resultVillage2,
                    BuildingId = "test",
                    BuildingSlot = "test",
                    Level = 1
                }
            })));
            _serviceProviderBuilder.WithService(actionProviderMock.Object);

            var buildActionResult = Builder <BaseScenarioResult> .CreateNew()
                                    .With(x => x.Success  = true)
                                    .With(x => x.Villages = new List <Village>
            {
                Builder <Village>
                .CreateNew()
                .With(y => y.CanBuild            = false)
                .With(y => y.Dorf1BuildTimeLeft  = TimeSpan.FromMinutes(2))
                .With(y => y.CoordinateX         = resultVillage.CoordinateX)
                .With(y => y.CoordinateY         = resultVillage.CoordinateY)
                .With(y => y.Warehourse          = 800)
                .With(y => y.Granary             = 800)
                .With(y => y.Resources           = Builder <Resources> .CreateNew().Build())
                .With(y => y.ResourcesProduction = Builder <Resources> .CreateNew().Build())
                .Build(),
                Builder <Village>
                .CreateNew()
                .With(y => y.CanBuild           = false)
                .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5))
                .With(y => y.CoordinateX        = resultVillage2.CoordinateX)
                .With(y => y.CoordinateY        = resultVillage2.CoordinateY)
                .Build()
            })
                                    .With(x => x.Errors = new List <ScenarioError>
            {
                Builder <BuildScenarioError>
                .CreateNew()
                .With(y => y.BuildErrorType = errorType)
                .With(y => y.Village        = resultVillage)
                .Build()
            })
                                    .Build();

            var gamePlayMock = new Mock <IGameplayClient>();

            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()))
            .Returns(Task.FromResult(infoResult));
            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()))
            .Returns(Task.FromResult(buildActionResult));
            _serviceProviderBuilder.WithService(gamePlayMock.Object);

            var cmd     = new FakeCommand();
            var cmdMock = new Mock <ICommandFactory>();

            cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>()))
            .Returns(cmd);
            _serviceProviderBuilder.WithService(cmdMock.Object);

            var job         = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build());
            var travianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true);
            var data        = new JobExecutionData
            {
                TravianUser = travianUser,
                JobType     = typeof(BuildingPlanExecutionJob)
            };

            var now = DateTimeOffset.Now;

            Assert.DoesNotThrowAsync(async() => await job.Execute(data));

            _serviceProviderBuilder.LoggerMock.Verify(x => x.Log(
                                                          LogLevel.Error,
                                                          It.IsAny <EventId>(),
                                                          It.IsAny <It.IsAnyType>(),
                                                          It.IsAny <Exception>(),
                                                          (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);

            gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Once);

            var expected = errorType == BuildErrorType.NoSpaceInQueue
                ? TimeSpan.FromMinutes(2)
                : Calculator.CalculateTimeForUnit(
                resultVillage,
                _serviceProviderBuilder.Mapper.Map <Village>(testVillage3),
                await _serviceProviderBuilder.UnitRepository.GetTrader(travianUser.PlayerData.Tribe));

            var diff = cmd.Start - now - TimeSpan.FromMinutes(2);

            Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now
            Assert.IsTrue(diff >= TimeSpan.FromSeconds(2));

            buildActionResult = Builder <BaseScenarioResult> .CreateNew()
                                .With(x => x.Success  = true)
                                .With(x => x.Villages = new List <Village>
            {
                Builder <Village>
                .CreateNew()
                .With(y => y.CanBuild    = true)
                .With(y => y.CoordinateX = resultVillage.CoordinateX)
                .With(y => y.CoordinateY = resultVillage.CoordinateY)
                .Build(),
                Builder <Village>
                .CreateNew()
                .With(y => y.CanBuild           = false)
                .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5))
                .With(y => y.CoordinateX        = resultVillage2.CoordinateX)
                .With(y => y.CoordinateY        = resultVillage2.CoordinateY)
                .Build()
            })
                                .With(x => x.Errors = new List <ScenarioError>
            {
                Builder <BuildScenarioError>
                .CreateNew()
                .With(y => y.BuildErrorType = errorType)
                .With(y => y.Village        = resultVillage)
                .Build()
            })
                                .Build();

            gamePlayMock = new Mock <IGameplayClient>();
            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()))
            .Returns(Task.FromResult(infoResult));
            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()))
            .Returns(Task.FromResult(buildActionResult));
            _serviceProviderBuilder.WithService(gamePlayMock.Object);

            job = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build());
            now = DateTimeOffset.Now;
            Assert.DoesNotThrowAsync(async() => await job.Execute(data));

            _serviceProviderBuilder.LoggerMock.Verify(x => x.Log(
                                                          LogLevel.Error,
                                                          It.IsAny <EventId>(),
                                                          It.IsAny <It.IsAnyType>(),
                                                          It.IsAny <Exception>(),
                                                          (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);

            gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Once);

            diff = cmd.Start - now;
            Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now
            Assert.IsTrue(diff >= TimeSpan.FromSeconds(2));
        }
        [TestCase(true, BuildErrorType.NoSpaceInQueue)]  // test one village with build action returns no space in queue error
        //[TestCase(true, BuildErrorType.NotEnoughResources)]
        public void Test_One_Village_Rescheduling_Next_Execution_Time(bool noSpaceInQueueError, BuildErrorType buildErrorType)
        {
            var testVillage   = PrepareTestOneVillage(isBuildingFeatureOn: true);
            var resultVillage = _serviceProviderBuilder.Mapper.Map <Village>(testVillage);
            var finishTime    = TimeSpan.FromMinutes(30);

            resultVillage.Dorf1BuildTimeLeft = finishTime;
            resultVillage.CanBuild           = true;
            resultVillage.Resources          = new Resources
            {
                Lumber = 100,
                Clay   = 100,
                Iron   = 100,
                Crop   = 100
            };
            resultVillage.Warehourse = 800;
            resultVillage.Granary    = 800;

            var infoResult = Builder <BaseScenarioResult> .CreateNew()
                             .With(x => x.Success  = true)
                             .With(x => x.Villages = new List <Village> {
                resultVillage
            })
                             .Build();

            var actionProviderMock = new Mock <IActionProvider>();

            actionProviderMock.Setup(x => x.GetBuildActions(resultVillage, It.IsAny <IEnumerable <BuildingModel> >()))
            .Returns(Task.FromResult((true, (IEnumerable <BuildAction>) new List <BuildAction> {
                new BuildAction
                {
                    Village = resultVillage,
                    BuildingId = "test",
                    BuildingSlot = "test",
                    Level = 1
                }
            })));
            _serviceProviderBuilder.WithService(actionProviderMock.Object);

            var buildActionResult = Builder <BaseScenarioResult> .CreateNew()
                                    .With(x => x.Success  = true)
                                    .With(x => x.Villages = new List <Village>
            {
                Builder <Village>
                .CreateNew()
                .With(y => y.CoordinateX        = resultVillage.CoordinateX)
                .With(y => y.CoordinateY        = resultVillage.CoordinateY)
                .With(y => y.CanBuild           = false)
                .With(y => y.Dorf1BuildTimeLeft = TimeSpan.FromMinutes(5))
                .Build()
            })
                                    .With(x => x.Errors = noSpaceInQueueError
                    ? new List <ScenarioError>
            {
                Builder <BuildScenarioError> .CreateNew()
                .With(y => y.BuildErrorType = buildErrorType)
                .With(y => y.Village        = resultVillage)
                .Build()
            }
                    : new List <ScenarioError>())
                                    .Build();

            var gamePlayMock = new Mock <IGameplayClient>();

            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <GameAction> >()))
            .Returns(Task.FromResult(infoResult));
            gamePlayMock.Setup(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()))
            .Returns(Task.FromResult(buildActionResult));
            _serviceProviderBuilder.WithService(gamePlayMock.Object);

            var cmd     = new FakeCommand();
            var cmdMock = new Mock <ICommandFactory>();

            cmdMock.Setup(x => x.GetQueueableCommand(nameof(BuildCommand), It.IsAny <long>()))
            .Returns(cmd);
            _serviceProviderBuilder.WithService(cmdMock.Object);

            var job  = new BuildingPlanExecutionJob(_serviceProviderBuilder.Build());
            var data = new JobExecutionData
            {
                TravianUser = FakeDataProvider.GetUser(PlayerStatus.ALL_QUIET, true),
                JobType     = typeof(BuildingPlanExecutionJob)
            };

            var now = DateTimeOffset.Now;

            Assert.DoesNotThrowAsync(async() => await job.Execute(data));

            _serviceProviderBuilder.LoggerMock.Verify(x => x.Log(
                                                          LogLevel.Error,
                                                          It.IsAny <EventId>(),
                                                          It.IsAny <It.IsAnyType>(),
                                                          It.IsAny <Exception>(),
                                                          (Func <It.IsAnyType, Exception, string>)It.IsAny <object>()), Times.Never);

            gamePlayMock.Verify(x => x.ExecuteActions(It.IsAny <TravianUser>(), It.IsAny <IEnumerable <BuildAction> >()), Times.Once);

            var diff = cmd.Start - now - TimeSpan.FromMinutes(5);

            Assert.IsTrue(diff <= TimeSpan.FromSeconds(3)); // will fail while debugging because of date time now
            Assert.IsTrue(diff >= TimeSpan.FromSeconds(2));
        }
Beispiel #14
0
        protected sealed override async Task ExecuteCommand(string parameters = "")
        {
            var jobData = new JobExecutionData
            {
                Cron        = Cron,
                JobType     = JobType,
                Start       = Start,
                TravianUser = _travianUser
            };

            var commandKey = SchedulerService.BuildJobKey(jobData);

            await CleanContext(commandKey);

            var isRunning = await _schedulerService.IsJobRunning(commandKey);

            if (_travianUser.ExecutionContext == null)
            {
                _travianUser.ExecutionContext = new ExecutionContextModel
                {
                    Commands       = new List <CommandModel>(),
                    IsUserNotified = false
                };
            }
            else if (_travianUser.ExecutionContext.Commands == null)
            {
                _travianUser.ExecutionContext.Commands = new List <CommandModel>();
            }
            if (_travianUser.PlayerData == null || string.IsNullOrEmpty(_travianUser.PlayerData?.TimeZone) || _travianUser.PlayerData.Tribe == Tribe.NOT_SPECIFIED)
            {
                var updateInfoResult = await _gameplayClient.RunUpdateUserInfo(_travianUser);

                _travianUser.PlayerData = new PlayerDataModel
                {
                    Status   = PlayerStatus.ALL_QUIET,
                    Tribe    = (Tribe)updateInfoResult.Player.Tribe,
                    TimeZone = updateInfoResult.Player.TimeZone,
                    // TODO: add alliance
                    UserName = _travianUser.UserName
                };
            }

            string msg;

            if (parameters.Contains("stop"))
            {
                if (isRunning)
                {
                    var stopResult = await _schedulerService.InterruptCommandAsync(commandKey);

                    if (stopResult)
                    {
                        var i = _travianUser.ExecutionContext.Commands.FindIndex(
                            x => x.Name == Name &&
                            x.KeyGroup == commandKey.Group &&
                            x.KeyName == commandKey.Name);

                        if (i > -1)
                        {
                            _travianUser.ExecutionContext.Commands[i].IsRunning = false;
                            await _travianUserRepository.Update(_travianUser);
                        }
                    }

                    msg = stopResult
                        ? $"The {Name} command for player {_travianUser.UserName} has been stopped."
                        : $"Can not stop the {Name} command for player {_travianUser.UserName}.";
                }
                else
                {
                    msg = $"The {Name} command is not running for player {_travianUser.UserName}.";
                }
            }
            else
            {
                if (isRunning)
                {
                    msg = $"The {Name} command is already being executing for player {_travianUser.UserName}.";
                }
                else
                {
                    msg = $"Starting the {Name} command for player {_travianUser.UserName}.";

                    await _schedulerService.ScheduleCommandAsync(jobData, new CancellationToken());

                    var i = _travianUser.ExecutionContext?.Commands?.FindIndex(
                        x => x.Name == Name &&
                        x.KeyGroup == commandKey.Group &&
                        x.KeyName == commandKey.Name &&
                        x.StartDateTime == Start);
                    if (i.HasValue && i > -1)
                    {
                        _travianUser.ExecutionContext.Commands[i.Value].IsRunning = true;
                    }
                    else
                    {
                        _travianUser.ExecutionContext.Commands.Add(new CommandModel
                        {
                            Name          = Name,
                            IsRunning     = true,
                            KeyName       = commandKey.Name,
                            KeyGroup      = commandKey.Group,
                            StartDateTime = Start
                        });
                    }

                    await _travianUserRepository.Update(_travianUser);
                }
            }

            await _bot.SendTextMessageAsync(_chatId, msg);
        }