コード例 #1
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_ActivityGroup_with_Id_exists_but_is_not_in_current_account_should_return_NotFound()
        {
            // Set up
            var otherPoll = new Poll
            {
                AccountId = Guid.NewGuid(),
                Id        = Guid.NewGuid()
            };

            Db.Mock.Polls.QueryData.Add(otherPoll);

            var group = InsertActivityGroup("x");

            group.PollId = otherPoll.Id;

            var request = new Messages.ActivityGroupMoveRequest
            {
                Id = group.Id
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (NotFoundObjectResult)rawReply;

            ((string)reply.Value).Should().NotBeNullOrWhiteSpace();
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #2
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        private ActivityGroup GetAffectedGroup(Messages.ActivityGroupMoveRequest request)
        {
            ActivityGroup group;

            if (request.Id.HasValue)
            {
                group = Db.Mock.ActivityGroups.QueryData.First(g => g.Id == request.Id);
            }
            else
            {
                group = Db.Mock.ActivityGroups.Added.First(g => g.MatchResponseText == request.MatchResponseText);
            }

            return(group);
        }
コード例 #3
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
 //======================= Private ===================================
 private void SetRequestProperty(Messages.ActivityGroupMoveRequest request, string what, string value)
 {
     if (what == "Id")
     {
         request.Id = new Guid(value);
     }
     else if (what == "MatchResponseText")
     {
         request.MatchResponseText = value;
     }
     else
     {
         throw new Exception($"Don't know how to set property '{what}'");
     }
 }
コード例 #4
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void May_not_make_activity_its_own_parent_when_targeting_by_MatchResponseText()
        {
            var request = new Messages.ActivityGroupMoveRequest();

            request.TargetParentMatchResponseText = "Some group";
            request.MatchResponseText             = "Some group";

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (BadRequestObjectResult)rawReply;

            ((string)reply.Value).Should().NotBeNullOrWhiteSpace();
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #5
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_Id_or_matchResponseText_are_missing_should_return_BadRequest()
        {
            // Set up
            var request = new Messages.ActivityGroupMoveRequest {
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (BadRequestObjectResult)rawReply;

            ((string)reply.Value).Should().Contain("id");
            ((string)reply.Value).Should().Contain("matchResponseText");
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #6
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_matchResponseText_is_too_long_should_return_BadRequest()
        {
            // Set up
            var request = new Messages.ActivityGroupMoveRequest
            {
                MatchResponseText = new string('a', ActivityGroup.MaxMatchResponseTextLength + 1)
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (BadRequestObjectResult)rawReply;

            ((string)reply.Value).Should().Contain("matchResponseText");
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #7
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_ActivityGroup_with_Id_does_not_exist_Should_return_NotFound()
        {
            // Set up
            var request = new Messages.ActivityGroupMoveRequest
            {
                Id = Guid.NewGuid()
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (NotFoundObjectResult)rawReply;

            ((string)reply.Value).Should().Contain("id");
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #8
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_target_has_Id_and_nothing_else_should_move_it_to_top_level()
        {
            // Set up.
            var parent = InsertActivityGroup("Parent");
            var child  = InsertActivityGroup("Child", parentId: parent.Id);

            var request = new Messages.ActivityGroupMoveRequest {
                Id = child.Id
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert.
            rawReply.Should().BeOfType <NoContentResult>();
            child.ParentId.Should().BeNull();
            Db.WasSaveChangesCalled.Should().Be(true);
        }
コード例 #9
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void May_not_target_ActivityGroup_by_MatchResponseText_if_it_already_exists()
        {
            var group   = InsertActivityGroup("Some group", matchResponseText: "Some group");
            var request = new Messages.ActivityGroupMoveRequest
            {
                MatchResponseText = "Some group"
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (BadRequestObjectResult)rawReply;

            ((string)reply.Value).Should().Contain("target");
            ((string)reply.Value).Should().Contain("id");
            ((string)reply.Value).Should().Contain("matchResponseText");
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #10
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_both_Id_and_matchResponseText_are_present_should_return_BadRequest()
        {
            // Set up
            var target  = InsertActivityGroup("x", matchResponseText: "x");
            var request = new Messages.ActivityGroupMoveRequest
            {
                Id = target.Id,
                MatchResponseText = "X"
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (BadRequestObjectResult)rawReply;

            ((string)reply.Value).Should().Contain("id");
            ((string)reply.Value).Should().Contain("matchResponseText");
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #11
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void If_target_has_matchResponseText_and_nothing_else_should_create_ActivityGroup_at_top_level()
        {
            // Set up.
            var request = new Messages.ActivityGroupMoveRequest
            {
                MatchResponseText = "New group"
            };

            // Act
            var rawReply = await _controller.Move(request);

            // Assert.
            rawReply.Should().BeOfType <NoContentResult>();
            var newGroup = Db.Mock.ActivityGroups.Added.First(g => g.MatchResponseText == "New group");

            newGroup.Name.Should().Be("New group");
            newGroup.ParentId.Should().BeNull();
            newGroup.PollId.Should().Be(DefaultPollId);

            Db.WasSaveChangesCalled.Should().Be(true);
        }
コード例 #12
0
ファイル: MoveTests.cs プロジェクト: ikhramts/maesure-oss
        public async void May_not_make_activity_its_own_ancestor_when_targeting_by_Id()
        {
            // Set up: try to make an activity a great-grandchild of itself.
            var grandparent = InsertActivityGroup("Grandparent");
            var parent      = InsertActivityGroup("Parent", parentId: grandparent.Id);
            var child       = InsertActivityGroup("Child", parentId: parent.Id);

            var request = new Messages.ActivityGroupMoveRequest();

            request.Id             = grandparent.Id;
            request.TargetParentId = child.Id;

            // Act
            var rawReply = await _controller.Move(request);

            // Assert
            var reply = (BadRequestObjectResult)rawReply;

            ((string)reply.Value).Should().NotBeNullOrWhiteSpace();
            Db.WasSaveChangesCalled.Should().Be(false);
        }
コード例 #13
0
        public async Task <IActionResult> Move([FromBody] Messages.ActivityGroupMoveRequest request)
        {
            // Validate that the user is logged in.
            var account = await GetCurrentAccountAsync();

            if (account == null)
            {
                return(Unauthorized());
            }

            // Basic validation.
            if (request.Id != null && !string.IsNullOrWhiteSpace(request.MatchResponseText))
            {
                return(BadRequest("Should not provide both 'id' and 'matchResponseText'"));
            }
            else if (request.Id == null && string.IsNullOrWhiteSpace(request.MatchResponseText))
            {
                return(BadRequest("Must provide either 'id' or 'matchResponseText'"));
            }

            var nameError = ValidateLength(request.MatchResponseText, ActivityGroup.MaxMatchResponseTextLength, "matchResponseText");

            if (nameError != null)
            {
                return(nameError);
            }

            var parentError = ValidateParentDescription(request.TargetParentId,
                                                        request.TargetParentMatchResponseText,
                                                        request.TargetGrandparentId,
                                                        "targetParent");

            if (parentError != null)
            {
                return(parentError);
            }

            if (request.TargetIsUncategorized != null &&
                (request.TargetParentId != null || !string.IsNullOrWhiteSpace(request.TargetParentMatchResponseText)))
            {
                return(BadRequest("Cannot provide 'targetIsUncategorized' when providing target parent details."));
            }

            if (!string.IsNullOrWhiteSpace(request.MatchResponseText) &&
                request.MatchResponseText == request.TargetParentMatchResponseText)
            {
                return(BadRequest("'matchResponseText' and 'targetParentMatchResponseText' cannot be the same. " +
                                  "Cannot make an activity group its own parent."));
            }

            // Data validation.
            Poll          poll          = null;
            ActivityGroup activityGroup = null;

            if (request.Id != null)
            {
                // This should be an actual activity group. Check if it exists.
                activityGroup = await Db.ActivityGroups.FirstOrDefaultAsync(g => g.Id == request.Id);

                if (activityGroup == null)
                {
                    return(NotFound($"Could not find ActivityGroup with id = {request.Id}"));
                }

                var pollId = activityGroup.PollId;
                poll = await Db.Polls.FirstOrDefaultAsync(p => p.Id == pollId);

                if (poll == null)
                {
                    throw new Exception($"Could not find a poll wit Id {pollId}");
                }
                else if (poll.AccountId != account.Id)
                {
                    return(NotFound($"Could not find ActivityGroup with id = {request.Id}"));
                }
            }
            else
            {
                // Confirm that this ActivityGroup does not exist.
                poll = await GetDefaultPollAsync();

                var existingGroup = await Db.ActivityGroups.FirstOrDefaultAsync(g => g.PollId == poll.Id &&
                                                                                g.MatchResponseText == request.MatchResponseText);

                if (existingGroup != null)
                {
                    return(BadRequest("There is already an ActivityGroup with matchResponseText = " +
                                      $"'{request.MatchResponseText}'. Its id is {existingGroup.Id}. Please target it by its id."));
                }

                // Create the activity group.
                activityGroup = new ActivityGroup
                {
                    Id   = Guid.NewGuid(),
                    Name = request.MatchResponseText,
                    MatchResponseText = request.MatchResponseText,
                    PollId            = poll.Id,
                    Position          = 0
                };

                Db.ActivityGroups.Add(activityGroup);
            }

            var parentExistsError = await ValidateGroupExists(poll,
                                                              request.TargetParentId,
                                                              request.TargetParentMatchResponseText,
                                                              request.TargetGrandparentId,
                                                              "target parent");

            if (parentExistsError != null)
            {
                return(parentExistsError);
            }

            // Make sure that this ActivityGroup will not be its own ancestor.
            var nextAncestorId = request.TargetParentId;

            while (nextAncestorId.HasValue)
            {
                var ancestor = await Db.ActivityGroups.FirstAsync(g => g.PollId == poll.Id && g.Id == nextAncestorId.Value);

                if (ancestor == null)
                {
                    break;
                }

                if (ancestor.Id == request.Id)
                {
                    return(BadRequest("Cannot make make ActivityGroup its own ancestor."));
                }

                nextAncestorId = ancestor.ParentId;
            }

            // User tracking.
            await UserEventsService.RecordEvent(new UserEvent
            {
                Account  = Account,
                Category = "activity_group",
                Name     = "move"
            });

            // Perform the move.
            if (request.TargetParentId == null && string.IsNullOrEmpty(request.TargetParentMatchResponseText))
            {
                // Move to the top level.
                activityGroup.ParentId = null;
            }
            else if (request.TargetParentId != null)
            {
                // Move it under the parent.
                activityGroup.ParentId = request.TargetParentId;
            }
            else if (!string.IsNullOrEmpty(request.TargetParentMatchResponseText))
            {
                // Create the target parent.
                var parent = new ActivityGroup
                {
                    Id   = Guid.NewGuid(),
                    Name = request.TargetParentMatchResponseText,
                    MatchResponseText = request.TargetParentMatchResponseText,
                    PollId            = poll.Id,
                    Position          = 0
                };

                if (request.TargetGrandparentId != null)
                {
                    parent.ParentId = request.TargetGrandparentId;
                }

                Db.ActivityGroups.Add(parent);
                activityGroup.ParentId = parent.Id;
            }
            else
            {
                // We should not enter here.
                throw new Exception("Reached unreacheable code in " + nameof(ActivityGroupsController) + ".Move().");
            }

            await Db.SaveChangesAsync();

            return(NoContent());
        }