Esempio n. 1
0
        public async Task <RaceResultDTO> AnalyseAsync(CreateRaceDTO createData, FileDTO file, string uploader)
        {
            //Validar minimamente os dados de input.
            if (createData == null || file == null || uploader == null)
            {
                throw new BusinessException("Dados inválidos para análise");
            }
            else if (!this.ValidateRequiredFields(createData, file, out string requiredFieldsErrorMessage))
            {
                throw new BusinessException(requiredFieldsErrorMessage);
            }

            //Processar o arquivo.
            await this._raceFileReader.Read(file.Content);

            //Tratar retorno.
            if (this.ValidatePostProcessing(out string postProcessingErrorMessage))
            {
                int newRaceId = await this.ProcessAndSaveData(createData, uploader, this._raceFileReader.Results);

                return(await this.GetResultByIdAsync(newRaceId));
            }
            else
            {
                throw new BusinessException(postProcessingErrorMessage);
            }
        }
Esempio n. 2
0
        public async Task Test_AnalyseAsync_InvalidPostProcessing_NoDataInFile()
        {
            //Arrange.
            CreateRaceDTO createRaceDTO = new CreateRaceDTO()
            {
                Date        = DateTime.Now,
                Description = "Descrição",
                TotalLaps   = 10,
                RaceTypeId  = 1
            };

            FileDTO fileDTO = new FileDTO()
            {
                Name        = "Arquivo teste",
                Content     = new MemoryStream(new byte[] { 125, 141, 13, 27 }),
                ContentType = "text/plain",
                Extension   = "txt"
            };

            //Mockar query para o tipo de corrida.
            var raceTypeByIdQuery = new Query <RaceType>();

            this._raceTypeQueryMock.Setup(x => x.ById(createRaceDTO.RaceTypeId))
            .Returns(raceTypeByIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceTypeRepositoryMock
            .Setup(rep => rep.Exists(It.Is <Query <RaceType> >(q => q.Equals(raceTypeByIdQuery))))
            .Returns(true);

            //Mockar mensagem, status do leitor de arquivo e coleção de voltas lidas.
            this._raceFileReaderMock.Setup(x => x.ErrorMessage)
            .Returns(string.Empty);

            this._raceFileReaderMock.Setup(x => x.Success)
            .Returns(true);

            this._raceFileReaderMock.Setup(x => x.Results)
            .Returns(Enumerable.Empty <Lap>());

            //Mockar chamada pro leitor de arquivos.
            this._raceFileReaderMock.Setup(x => x.Read(It.IsAny <Stream>()))
            .Returns(Task.CompletedTask);

            //Act.
            await this._raceService.AnalyseAsync(createRaceDTO, fileDTO, "yagohf");

            //Assert.
        }
Esempio n. 3
0
        public async Task <IActionResult> Post([FromForm] CreateRaceDTO model, [FromForm] IFormFile file)
        {
            FileDTO fileDTO = new FileDTO();

            if (file != null && file.Length > 0)
            {
                fileDTO.Extension   = file.FileName.Split('.').Last();
                fileDTO.ContentType = file.ContentType;
                fileDTO.Content     = new MemoryStream();
                await file.CopyToAsync(fileDTO.Content);
            }

            RaceResultDTO raceResult = await this._raceService.AnalyseAsync(model, fileDTO, this.GetLoggedUser());

            return(CreatedAtAction(nameof(GetResultById), new { id = raceResult.RaceId }, raceResult));
        }
Esempio n. 4
0
        private async Task <int> ProcessAndSaveData(CreateRaceDTO createData, string uploader, IEnumerable <Lap> laps)
        {
            //Recuperar usuário da corrida.
            User user = await this._userRepository.GetSingleAsync(this._userQuery.ByLogin(uploader));

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                //Salvar corrida.
                Race race = new Race();
                race.Date        = createData.Date;
                race.Description = createData.Description;
                race.TotalLaps   = createData.TotalLaps;
                race.UploadDate  = DateTime.Now;
                race.UploaderId  = user.Id;
                race.RaceTypeId  = createData.RaceTypeId;

                await this._raceRepository.InsertAsync(race);

                //Salvar cada uma das voltas após atualizar o ID da corrida.
                foreach (var lap in laps)
                {
                    lap.RaceId = race.Id;
                    await this._lapRepository.InsertAsync(lap);
                }

                //Processar o resultado dos pilotos e persistir resultados.
                IEnumerable <DriverResult> driverResults = this.ProcessDriverResults(laps);
                foreach (var driverResult in driverResults)
                {
                    driverResult.RaceId = race.Id;
                    await this._driverResultRepository.InsertAsync(driverResult);
                }

                //Commitar transação.
                ts.Complete();

                //Devolver ID para o chamador.
                return(race.Id);
            }
        }
Esempio n. 5
0
        private bool ValidateRequiredFields(CreateRaceDTO createData, FileDTO file, out string requiredFieldsErrorMessage)
        {
            requiredFieldsErrorMessage = string.Empty;
            if (string.IsNullOrWhiteSpace(createData.Description))
            {
                requiredFieldsErrorMessage += "Descrição não informada;";
            }
            if (createData.TotalLaps < 1)
            {
                requiredFieldsErrorMessage += "Número de voltas inválido;";
            }
            if (file.Content == null || file.Content.Length == 0 || this._raceFileSettings.AllowedContentType != file.ContentType)
            {
                requiredFieldsErrorMessage += "Arquivo inválido para análise;";
            }
            if (!this._raceTypeRepository.Exists(this._raceTypeQuery.ById(createData.RaceTypeId)))
            {
                requiredFieldsErrorMessage += "Tipo de corrida inválido;";
            }

            return(string.IsNullOrEmpty(requiredFieldsErrorMessage));
        }
Esempio n. 6
0
        public async Task Test_AnalyseAsync_InvalidFileContent()
        {
            //Arrange.
            CreateRaceDTO createRaceDTO = new CreateRaceDTO()
            {
                Date        = DateTime.Now,
                Description = "Teste",
                TotalLaps   = 1,
                RaceTypeId  = 1
            };

            FileDTO fileDTO = new FileDTO()
            {
                Name        = "Teste",
                Content     = new MemoryStream(new byte[] { 125, 141, 13, 27 }),
                ContentType = "application/octet-stream",
                Extension   = "pdf"
            };

            //Mockar query para o tipo de corrida.
            var raceTypeByIdQuery = new Query <RaceType>();

            this._raceTypeQueryMock.Setup(x => x.ById(createRaceDTO.RaceTypeId))
            .Returns(raceTypeByIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceTypeRepositoryMock
            .Setup(rep => rep.Exists(It.Is <IQuery <RaceType> >(q => q.Equals(raceTypeByIdQuery))))
            .Returns(true);


            //Act.
            await this._raceService.AnalyseAsync(createRaceDTO, fileDTO, "yagohf");

            //Assert.
        }
Esempio n. 7
0
        public async Task Test_AnalyseAsync_InvalidCreateData()
        {
            //Arrange.
            CreateRaceDTO createRaceDTO = new CreateRaceDTO()
            {
                Date        = DateTime.Now,
                Description = "",
                TotalLaps   = -10,
                RaceTypeId  = 300
            };

            FileDTO fileDTO = new FileDTO()
            {
                Name        = "",
                Content     = null,
                ContentType = "",
                Extension   = ""
            };

            //Mockar query para o tipo de corrida.
            var raceTypeByIdQuery = new Query <RaceType>();

            this._raceTypeQueryMock.Setup(x => x.ById(createRaceDTO.RaceTypeId))
            .Returns(raceTypeByIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceTypeRepositoryMock
            .Setup(rep => rep.Exists(It.Is <IQuery <RaceType> >(q => q.Equals(raceTypeByIdQuery))))
            .Returns(false);


            //Act.
            await this._raceService.AnalyseAsync(createRaceDTO, fileDTO, "yagohf");

            //Assert.
        }
Esempio n. 8
0
        public async Task Test_AnalyseAsync_Valid()
        {
            //Arrange.
            CreateRaceDTO createRaceDTO = new CreateRaceDTO()
            {
                Date        = DateTime.Now.Date,
                Description = "Race Unit Test",
                TotalLaps   = 1,
                RaceTypeId  = 1
            };

            FileDTO fileDTO = new FileDTO()
            {
                Name        = "Arquivo teste",
                Content     = new MemoryStream(new byte[] { 125, 141, 13, 27 }),
                ContentType = "text/plain",
                Extension   = "txt"
            };

            List <Lap> resultsMock = new List <Lap>()
            {
                new Lap()
                {
                    DriverNumber = 10, DriverName = "F. Alonso", Number = 1
                },
                new Lap()
                {
                    DriverNumber = 11, DriverName = "F. Massa", Number = 1
                }
            };

            RaceType raceTypeMock = new RaceType()
            {
                Id   = 1,
                Name = "F-1"
            };

            //Mockar query para o tipo de corrida.
            var raceTypeByIdQuery = new Query <RaceType>();

            this._raceTypeQueryMock.Setup(x => x.ById(createRaceDTO.RaceTypeId))
            .Returns(raceTypeByIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceTypeRepositoryMock
            .Setup(rep => rep.Exists(It.Is <Query <RaceType> >(q => q.Equals(raceTypeByIdQuery))))
            .Returns(true);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceTypeRepositoryMock
            .Setup(rep => rep.GetSingleAsync(It.Is <IQuery <RaceType> >(q => q.Equals(raceTypeByIdQuery))))
            .Returns(Task.FromResult(raceTypeMock));

            //Mockar mensagem, status do leitor de arquivo e coleção de voltas lidas.
            this._raceFileReaderMock.Setup(x => x.ErrorMessage)
            .Returns(string.Empty);

            this._raceFileReaderMock.Setup(x => x.Success)
            .Returns(true);

            this._raceFileReaderMock.Setup(x => x.Results)
            .Returns(resultsMock);

            //Mockar chamada pro leitor de arquivos.
            this._raceFileReaderMock.Setup(x => x.Read(It.IsAny <Stream>()))
            .Returns(Task.CompletedTask);

            //Mockar query para o usuário por login.
            User userMock = new User()
            {
                Id    = 1,
                Login = "******"
            };
            var userByLoginQuery = new Query <User>();

            this._userQueryMock.Setup(x => x.ByLogin(userMock.Login))
            .Returns(userByLoginQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._userRepositoryMock
            .Setup(rep => rep.GetSingleAsync(It.Is <Query <User> >(q => q.Equals(userByLoginQuery))))
            .Returns(Task.FromResult(userMock));

            //Mockar inserts.
            this._raceRepositoryMock.Setup(x => x.InsertAsync(It.IsAny <Race>()))
            .Returns(Task.CompletedTask);

            this._lapRepositoryMock.Setup(x => x.InsertAsync(It.IsAny <Lap>()))
            .Returns(Task.CompletedTask);

            this._driverResultRepositoryMock.Setup(x => x.InsertAsync(It.IsAny <DriverResult>()))
            .Returns(Task.CompletedTask);

            #region [ Preparar cenário do GetResultsById ]

            Race raceMock = new Race()
            {
                Date        = DateTime.Now.Date,
                Description = "Race Unit Test",
                RaceTypeId  = 1,
                TotalLaps   = 1,
                UploadDate  = DateTime.Now.Date,
                Uploader    = new User()
                {
                    Id       = 1,
                    Login    = "******",
                    Name     = "Yago",
                    Password = "******"
                }
            };

            //Mockar query.
            var raceByIdQuery = new Query <Race>();
            this._raceQueryMock.Setup(x => x.ById(raceMock.Id))
            .Returns(raceByIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceRepositoryMock
            .Setup(rep => rep.GetSingleAsync(It.Is <IQuery <Race> >(q => q.Equals(raceByIdQuery))))
            .Returns(Task.FromResult(raceMock));

            List <DriverResult> driverResultsMock = new List <DriverResult>()
            {
                new DriverResult()
                {
                    Id            = 1,
                    AverageSpeed  = 10,
                    BestLap       = TimeSpan.FromSeconds(10),
                    DriverName    = "F. Alonso",
                    DriverNumber  = 10,
                    Gap           = null,
                    Laps          = 1,
                    Position      = 1,
                    RaceId        = raceMock.Id,
                    TotalRaceTime = TimeSpan.FromSeconds(10)
                },
                new DriverResult()
                {
                    Id            = 2,
                    AverageSpeed  = 8,
                    BestLap       = TimeSpan.FromSeconds(15),
                    DriverName    = "F. Massa",
                    DriverNumber  = 11,
                    Gap           = TimeSpan.FromSeconds(5),
                    Laps          = 1,
                    Position      = 1,
                    RaceId        = raceMock.Id,
                    TotalRaceTime = TimeSpan.FromSeconds(15)
                }
            };

            //Mockar query de corrida por id.
            var driverResultsByRaceIdQuery = new Query <DriverResult>();
            this._driverResultQueryMock.Setup(x => x.ByRace(raceMock.Id))
            .Returns(driverResultsByRaceIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._driverResultRepositoryMock
            .Setup(rep => rep.ListAsync(It.Is <IQuery <DriverResult> >(q => q.Equals(driverResultsByRaceIdQuery))))
            .Returns(Task.FromResult(driverResultsMock.AsEnumerable()));

            #endregion

            //Act.
            var result = await this._raceService.AnalyseAsync(createRaceDTO, fileDTO, userMock.Login);

            //Assert.
            Assert.IsNotNull(result);
        }
Esempio n. 9
0
        public async Task Test_AnalyseAsync_InvalidPostProcessing_RanTheSameLapTwice()
        {
            //Arrange.
            CreateRaceDTO createRaceDTO = new CreateRaceDTO()
            {
                Date        = DateTime.Now,
                Description = "Descrição",
                TotalLaps   = 10,
                RaceTypeId  = 1
            };

            FileDTO fileDTO = new FileDTO()
            {
                Name        = "Arquivo teste",
                Content     = new MemoryStream(new byte[] { 125, 141, 13, 27 }),
                ContentType = "text/plain",
                Extension   = "txt"
            };

            List <Lap> resultsMock = new List <Lap>()
            {
                new Lap()
                {
                    DriverNumber = 10, DriverName = "F. Alonso", Number = 1
                },
                new Lap()
                {
                    DriverNumber = 10, DriverName = "F. Alonso", Number = 1
                }
            };

            //Mockar query para o tipo de corrida.
            var raceTypeByIdQuery = new Query <RaceType>();

            this._raceTypeQueryMock.Setup(x => x.ById(createRaceDTO.RaceTypeId))
            .Returns(raceTypeByIdQuery);

            //Mockar retorno do repositório quando usamos a query criada.
            this._raceTypeRepositoryMock
            .Setup(rep => rep.Exists(It.Is <Query <RaceType> >(q => q.Equals(raceTypeByIdQuery))))
            .Returns(true);

            //Mockar mensagem, status do leitor de arquivo e coleção de voltas lidas.
            this._raceFileReaderMock.Setup(x => x.ErrorMessage)
            .Returns(string.Empty);

            this._raceFileReaderMock.Setup(x => x.Success)
            .Returns(true);

            this._raceFileReaderMock.Setup(x => x.Results)
            .Returns(resultsMock);

            //Mockar chamada pro leitor de arquivos.
            this._raceFileReaderMock.Setup(x => x.Read(It.IsAny <Stream>()))
            .Returns(Task.CompletedTask);

            string exceptionMessage = null;

            //Act.
            try
            {
                await this._raceService.AnalyseAsync(createRaceDTO, fileDTO, "yagohf");
            }
            catch (Exception ex)
            {
                exceptionMessage = ex.Message;
            }

            //Assert.
            Assert.IsNotNull(exceptionMessage);
            Assert.IsTrue(exceptionMessage.StartsWith("Existem voltas repetidas para o mesmo piloto:"));
            Assert.IsTrue(exceptionMessage.Contains($"Piloto: {resultsMock.First().DriverNumber} / Volta: { resultsMock.First().Number }"));
        }
Esempio n. 10
0
        public async Task Test_Post()
        {
            //Arrange.
            CreateRaceDTO createRaceMock = new CreateRaceDTO()
            {
                Date        = DateTime.Now.AddDays(-1),
                Description = "2019 F-1 Racing",
                RaceTypeId  = 1,
                TotalLaps   = 10
            };

            //Arrange.
            int           raceId         = 1;
            RaceResultDTO raceResultMock = new RaceResultDTO()
            {
                BestLap = new BestLapDTO()
                {
                    Driver = "10 - Test Driver",
                    Time   = TimeSpan.FromSeconds(60)
                },
                RaceDate        = DateTime.Now.AddDays(-1),
                RaceDescription = "2019 F-1 Racing",
                RaceId          = raceId,
                TotalLaps       = 10,
                UploadDate      = DateTime.Now.Date,
                Uploader        = "yagohf",
                Winner          = "10 - Test Driver",
                Results         = new List <DriverResultDTO>()
                {
                    new DriverResultDTO()
                    {
                        AverageSpeed  = 40,
                        BestLap       = TimeSpan.FromSeconds(60),
                        DriverName    = "Test Driver",
                        DriverNumber  = 10,
                        Gap           = null,
                        Laps          = 10,
                        Position      = 1,
                        TotalRaceTime = TimeSpan.FromMinutes(15)
                    },
                    new DriverResultDTO()
                    {
                        AverageSpeed  = 38,
                        BestLap       = TimeSpan.FromSeconds(70),
                        DriverName    = "Test Driver 2",
                        DriverNumber  = 15,
                        Gap           = TimeSpan.FromSeconds(60),
                        Laps          = 10,
                        Position      = 2,
                        TotalRaceTime = TimeSpan.FromMinutes(16)
                    }
                }
            };

            //Mockar arquivo.
            Mock <IFormFile> fileMock         = new Mock <IFormFile>();
            string           fileName         = "NO-ERRORS.txt";
            string           fileAssemblyPath = $"Yagohf.Gympass.RaceAnalyser.UnitTests.Embedded.{fileName}";

            using (var fileAssemblyStream = Assembly.GetAssembly(typeof(RacesControllerTests)).GetManifestResourceStream(fileAssemblyPath))
            {
                fileAssemblyStream.Position = 0;
                fileMock.Setup(x => x.OpenReadStream()).Returns(fileAssemblyStream);
                fileMock.Setup(x => x.FileName).Returns(fileName);
                fileMock.Setup(x => x.Length).Returns(fileAssemblyStream.Length);
                fileMock.Setup(x => x.ContentType).Returns("text/plain");
            }

            //Mockar usuário logado.
            var claims = new List <Claim>()
            {
                new Claim(ClaimTypes.Name, "yagohf"),
            };

            var identity        = new ClaimsIdentity(claims);
            var claimsPrincipal = new ClaimsPrincipal(identity);

            var principalMock = new Mock <IPrincipal>();

            principalMock.Setup(x => x.Identity).Returns(identity);

            var mockHttpContext = new Mock <HttpContext>();

            mockHttpContext.Setup(m => m.User).Returns(claimsPrincipal);

            this._racesController.ControllerContext.HttpContext = mockHttpContext.Object;

            this._raceServiceMock
            .Setup(srv => srv.AnalyseAsync(It.IsAny <CreateRaceDTO>(), It.IsAny <FileDTO>(), It.IsAny <string>()))
            .Returns(Task.FromResult(raceResultMock));

            //Act.
            var result = await this._racesController.Post(createRaceMock, fileMock.Object);

            var createdAtResult = result as CreatedAtActionResult;

            //Assert.
            Assert.IsNotNull(createdAtResult);
            Assert.IsInstanceOfType(createdAtResult.Value, typeof(RaceResultDTO));
            Assert.AreEqual(raceResultMock, createdAtResult.Value as RaceResultDTO);

            //Testar URL de redirecionamento.
            Assert.AreEqual(createdAtResult.ActionName, nameof(this._racesController.GetResultById));
            Assert.AreEqual(createdAtResult.RouteValues["id"], raceResultMock.RaceId);
        }