/// <summary>
        /// Handles the command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        private async Task HandleCommand(CreateTournamentCommand command,
                                         CancellationToken cancellationToken)
        {
            // Rehydrate the aggregate
            TournamentAggregate tournament = await this.TournamentRepository.GetLatestVersion(command.TournamentId, cancellationToken);

            // Get the club to validate the input
            GolfClubAggregate club = await this.GolfClubRepository.GetLatestVersion(command.GolfClubId, cancellationToken);

            // bug #29 fixes (throw exception if club not created)
            if (!club.HasBeenCreated)
            {
                throw new NotFoundException($"No created golf club found with Id {command.GolfClubId}");
            }

            // Club is valid, now check the measured course, this will throw exception if not found
            MeasuredCourseDataTransferObject measuredCourse = club.GetMeasuredCourse(command.CreateTournamentRequest.MeasuredCourseId);

            tournament.CreateTournament(command.CreateTournamentRequest.TournamentDate,
                                        command.GolfClubId,
                                        command.CreateTournamentRequest.MeasuredCourseId,
                                        measuredCourse.StandardScratchScore,
                                        command.CreateTournamentRequest.Name,
                                        (PlayerCategory)command.CreateTournamentRequest.MemberCategory,
                                        (TournamentFormat)command.CreateTournamentRequest.Format);

            // Save the changes
            await this.TournamentRepository.SaveChanges(tournament, cancellationToken);

            // Setup the response
            command.Response = new CreateTournamentResponse
            {
                TournamentId = command.TournamentId
            };
        }
        public void GolfClubAggregate_GetMeasuredCourse_MeasuredCourseWithHolesReturned()
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetGolfClubAggregateWithMeasuredCourse();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            MeasuredCourseDataTransferObject measuredCourse = aggregate.GetMeasuredCourse(measuredCourseDataTransferObject.MeasuredCourseId);

            measuredCourse.ShouldNotBeNull();
            measuredCourse.Name.ShouldBe(measuredCourseDataTransferObject.Name);
            measuredCourse.StandardScratchScore.ShouldBe(measuredCourseDataTransferObject.StandardScratchScore);
            measuredCourse.TeeColour.ShouldBe(measuredCourseDataTransferObject.TeeColour);
            measuredCourse.Holes.Count.ShouldBe(measuredCourseDataTransferObject.Holes.Count);

            IOrderedEnumerable <HoleDataTransferObject> resultHoles = measuredCourse.Holes.OrderBy(m => m.HoleNumber);

            foreach (HoleDataTransferObject holeDataTransferObject in resultHoles)
            {
                HoleDataTransferObject orignalHole = measuredCourseDataTransferObject.Holes.Single(h => h.HoleNumber == holeDataTransferObject.HoleNumber);

                holeDataTransferObject.HoleNumber.ShouldBe(orignalHole.HoleNumber);
                holeDataTransferObject.LengthInMeters.ShouldBe(orignalHole.LengthInMeters);
                holeDataTransferObject.LengthInYards.ShouldBe(orignalHole.LengthInYards);
                holeDataTransferObject.Par.ShouldBe(orignalHole.Par);
                holeDataTransferObject.StrokeIndex.ShouldBe(orignalHole.StrokeIndex);
            }
        }
        public void GolfClubAggregate_AddMeasuredCourse_InvalidHoleData_MissingHoleNumber_ErrorThrown(Int32 holeNumber)
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetCreatedGolfClubAggregate();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAddWithMissingHoles(holeNumber);

            Should.Throw <InvalidDataException>(() => { aggregate.AddMeasuredCourse(measuredCourseDataTransferObject); });
        }
        public void GolfClubAggregate_GetMeasuredCourses_NoCourses_ErrorThrown()
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetCreatedGolfClubAggregate();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            Should.Throw <NotFoundException>(() => { aggregate.GetMeasuredCourses(); });
        }
        public void GolfClubAggregate_GetMeasuredCourse_MeasuredCourseNotFound_ErrorThrown()
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetGolfClubAggregateWithMeasuredCourse();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            Should.Throw <NotFoundException>(() => { aggregate.GetMeasuredCourse(GolfClubTestData.InvalidMeasuredCourseId); });
        }
        public void GolfClubAggregate_AddMeasuredCourse_ClubNotCreated_ErrorThrown()
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetEmptyGolfClubAggregate();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            Should.Throw <InvalidOperationException>(() => { aggregate.AddMeasuredCourse(measuredCourseDataTransferObject); });
        }
        public void GolfClubAggregate_AddMeasuredCourse_InvalidNumberOfHoles_ErrorThrown(Int32 numberHoles)
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetCreatedGolfClubAggregate();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd(numberHoles);

            Should.Throw <InvalidDataException>(() => { aggregate.AddMeasuredCourse(measuredCourseDataTransferObject); });
        }
        public void GolfClubAggregate_AddMeasuredCourse_InvalidHoleData_InvalidData_ErrorThrown(Int32 lengthInYards,
                                                                                                Int32 par)
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetCreatedGolfClubAggregate();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            measuredCourseDataTransferObject.Holes.First().LengthInYards = lengthInYards;
            measuredCourseDataTransferObject.Holes.First().Par           = par;
            Should.Throw <InvalidDataException>(() => { aggregate.AddMeasuredCourse(measuredCourseDataTransferObject); });
        }
        public void GolfClubAggregate_GetMeasuredCourses_MeasuredCoursesReturned()
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetGolfClubAggregateWithMeasuredCourse();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            List <MeasuredCourseDataTransferObject> measuredCourses = aggregate.GetMeasuredCourses();

            measuredCourses.ShouldNotBeEmpty();
            measuredCourses.First().MeasuredCourseId.ShouldBe(measuredCourseDataTransferObject.MeasuredCourseId);
            measuredCourses.First().Name.ShouldBe(measuredCourseDataTransferObject.Name);
            measuredCourses.First().TeeColour.ShouldBe(measuredCourseDataTransferObject.TeeColour);
            measuredCourses.First().StandardScratchScore.ShouldBe(measuredCourseDataTransferObject.StandardScratchScore);
        }
        public void GolfClubAggregate_AddMeasuredCourse_InvalidCourseData_ErrorThrown(Boolean validMeasuredCourseId,
                                                                                      String name,
                                                                                      String teeColour,
                                                                                      Int32 standardScratchScore)
        {
            GolfClubAggregate aggregate = GolfClubTestData.GetCreatedGolfClubAggregate();

            MeasuredCourseDataTransferObject measuredCourseDataTransferObject = GolfClubTestData.GetMeasuredCourseToAdd();

            measuredCourseDataTransferObject.MeasuredCourseId     = validMeasuredCourseId ? GolfClubTestData.MeasuredCourseId : Guid.Empty;
            measuredCourseDataTransferObject.Name                 = name;
            measuredCourseDataTransferObject.TeeColour            = teeColour;
            measuredCourseDataTransferObject.StandardScratchScore = standardScratchScore;

            Should.Throw <ArgumentNullException>(() => { aggregate.AddMeasuredCourse(measuredCourseDataTransferObject); });
        }
        /// <summary>
        /// Handles the command.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns></returns>
        private async Task HandleCommand(AddMeasuredCourseToClubCommand command,
                                         CancellationToken cancellationToken)
        {
            // Rehydrate the aggregate
            GolfClubAggregate golfClubAggregate = await this.GolfClubRepository.GetLatestVersion(command.GolfClubId, cancellationToken);

            // Translate the request to the input for AddMeasuredCourse
            MeasuredCourseDataTransferObject measuredCourse = new MeasuredCourseDataTransferObject
            {
                MeasuredCourseId     = command.MeasuredCourseId,
                Name                 = command.AddMeasuredCourseToClubRequest.Name,
                StandardScratchScore = command.AddMeasuredCourseToClubRequest.StandardScratchScore,
                TeeColour            = command.AddMeasuredCourseToClubRequest.TeeColour,
                Holes                = new List <HoleDataTransferObject>()
            };

            foreach (HoleDataTransferObjectRequest holeDataTransferObject in command.AddMeasuredCourseToClubRequest.Holes)
            {
                measuredCourse.Holes.Add(new HoleDataTransferObject
                {
                    HoleNumber     = holeDataTransferObject.HoleNumber,
                    Par            = holeDataTransferObject.Par,
                    StrokeIndex    = holeDataTransferObject.StrokeIndex,
                    LengthInYards  = holeDataTransferObject.LengthInYards,
                    LengthInMeters = holeDataTransferObject.LengthInMeters
                });
            }

            // Add the measured course
            golfClubAggregate.AddMeasuredCourse(measuredCourse);

            // Save the changes
            await this.GolfClubRepository.SaveChanges(golfClubAggregate, cancellationToken);

            // No Response to set
        }