From bb36881807550ea39988457d2d048b8274e8affc Mon Sep 17 00:00:00 2001 From: Christophe Ninucci Date: Fri, 15 Dec 2023 15:43:06 +0100 Subject: [PATCH 1/2] =?UTF-8?q?-=20fonction=20pour=20retirer=20un=20assign?= =?UTF-8?q?=C3=A9=20d'une=20carte=20avec=20l'activit=C3=A9=20correspondant?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- activities.go | 13 +++++++++++++ users.go | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/activities.go b/activities.go index 7317ddb..cd9ca50 100644 --- a/activities.go +++ b/activities.go @@ -118,6 +118,19 @@ func newActivityCardUnjoinMember(userID UserID, username Username, memberID User } } +func newActivityCardUnjoinAssignee(userID UserID, username Username, assigneeID UserID, boardID BoardID, listID ListID, cardID CardID, swimlaneID SwimlaneID) Activity { + return Activity{ + UserID: userID, + Username: username, + MemberID: assigneeID, + BoardID: boardID, + CardID: cardID, + ListID: listID, + SwimlaneID: swimlaneID, + ActivityType: "unjoinAssignee", + } +} + func newActivityAddComment(userID UserID, boardID BoardID, cardID CardID, commentID CommentID, listID ListID, swimlaneID SwimlaneID) Activity { return Activity{ UserID: userID, diff --git a/users.go b/users.go index 956a34b..0b9d97d 100644 --- a/users.go +++ b/users.go @@ -501,6 +501,45 @@ func (wekan *Wekan) RemoveMemberFromCard(ctx context.Context, card Card, user Us return nil } +func (wekan *Wekan) RemoveAssigneeFromCard(ctx context.Context, card Card, user User, assignee User) error { + if err := wekan.AssertPrivileged(ctx); err != nil { + return err + } + if err := wekan.CheckDocuments(ctx, card.ID, assignee.ID); err != nil { + return err + } + + stats, err := wekan.db.Collection("cards").UpdateOne(ctx, bson.M{ + "_id": card.ID, + }, bson.M{ + "$pull": bson.M{ + "assignees": assignee.ID, + }, + }) + if stats.ModifiedCount == 0 { + return NothingDoneError{} + } + if err != nil { + return UnexpectedMongoError{err} + } + + activity := newActivityCardUnjoinAssignee(user.ID, assignee.Username, assignee.ID, card.BoardID, card.ListID, card.ID, card.SwimlaneID) + _, err = wekan.insertActivity(ctx, activity) + if err != nil { + return UnexpectedMongoError{err: err} + } + + return nil +} + +func (wekan *Wekan) EnsureAssigneeOutOfCard(ctx context.Context, card Card, user User, assignee User) (bool, error) { + err := wekan.RemoveAssigneeFromCard(ctx, card, user, assignee) + if _, ok := err.(NothingDoneError); ok { + return false, nil + } + return err == nil, err +} + func (wekan *Wekan) EnsureMemberOutOfCard(ctx context.Context, card Card, user User, member User) (bool, error) { err := wekan.RemoveMemberFromCard(ctx, card, user, member) if _, ok := err.(NothingDoneError); ok { From 80464fb9bfa43708ac2689d085c95e40ffb94435 Mon Sep 17 00:00:00 2001 From: Christophe Ninucci Date: Tue, 19 Dec 2023 14:27:58 +0100 Subject: [PATCH 2/2] - ajout / suppression d'assignees dans les cartes - les tests qui vont avec --- activities.go | 16 +++++++++- users.go | 65 ++++++++++++++++++++++++++++++++++++--- users_integration_test.go | 54 ++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 5 deletions(-) diff --git a/activities.go b/activities.go index cd9ca50..6204fbb 100644 --- a/activities.go +++ b/activities.go @@ -15,6 +15,7 @@ type Activity struct { UserID UserID `bson:"userId,omitempty" json:"userId,omitempty"` Username Username `bson:"username,omitempty" json:"username,omitempty"` Type string `bson:"type,omitempty" json:"type,omitempty"` + AssigneeID UserID `bson:"assigneeId,omitempty" json:"assigneeId,omitempty"` MemberID UserID `bson:"memberId,omitempty" json:"memberId,omitempty"` ActivityType string `bson:"activityType,omitempty" json:"activityType,omitempty"` ActivityTypeID string `bson:"activityTypeId,omitempty" json:"activityTypeId,omitempty"` @@ -105,6 +106,19 @@ func newActivityCardJoinMember(userID UserID, username Username, memberID UserID } } +func newActivityCardJoinAssignee(userID UserID, username Username, memberID UserID, boardID BoardID, listID ListID, cardID CardID, swimlaneID SwimlaneID) Activity { + return Activity{ + UserID: userID, + Username: username, + AssigneeID: memberID, + BoardID: boardID, + CardID: cardID, + ListID: listID, + SwimlaneID: swimlaneID, + ActivityType: "joinAssignee", + } +} + func newActivityCardUnjoinMember(userID UserID, username Username, memberID UserID, boardID BoardID, listID ListID, cardID CardID, swimlaneID SwimlaneID) Activity { return Activity{ UserID: userID, @@ -122,7 +136,7 @@ func newActivityCardUnjoinAssignee(userID UserID, username Username, assigneeID return Activity{ UserID: userID, Username: username, - MemberID: assigneeID, + AssigneeID: assigneeID, BoardID: boardID, CardID: cardID, ListID: listID, diff --git a/users.go b/users.go index 0b9d97d..a0ef031 100644 --- a/users.go +++ b/users.go @@ -510,18 +510,19 @@ func (wekan *Wekan) RemoveAssigneeFromCard(ctx context.Context, card Card, user } stats, err := wekan.db.Collection("cards").UpdateOne(ctx, bson.M{ - "_id": card.ID, + "_id": card.ID, + "assignees": bson.M{"$type": 4}, }, bson.M{ "$pull": bson.M{ "assignees": assignee.ID, }, }) - if stats.ModifiedCount == 0 { - return NothingDoneError{} - } if err != nil { return UnexpectedMongoError{err} } + if stats.ModifiedCount == 0 { + return NothingDoneError{} + } activity := newActivityCardUnjoinAssignee(user.ID, assignee.Username, assignee.ID, card.BoardID, card.ListID, card.ID, card.SwimlaneID) _, err = wekan.insertActivity(ctx, activity) @@ -552,6 +553,62 @@ func (wekan *Wekan) AddSelfMemberToCard(ctx context.Context, card Card, member U return wekan.AddMemberToCard(ctx, card, member, member) } +func (wekan *Wekan) AddAssigneeToCard(ctx context.Context, card Card, user User, assignee User) error { + if err := wekan.AssertPrivileged(ctx); err != nil { + return err + } + board, err := wekan.GetBoardFromID(ctx, card.BoardID) + if err != nil { + return err + } + + if !board.UserIsActiveMember(assignee) { + return ForbiddenOperationError{ + UserIsNotMemberError{assignee.ID}, + } + } + + if !board.UserIsActiveMember(user) { + return ForbiddenOperationError{ + UserIsNotMemberError{user.ID}, + } + } + + _, err = wekan.db.Collection("cards").UpdateOne(ctx, bson.M{ + "_id": card.ID, + "assignees": nil, + }, bson.M{ + "$set": bson.M{"assignees": bson.A{}}, + }) + + if err != nil { + return UnexpectedMongoError{err} + } + + stats, err := wekan.db.Collection("cards").UpdateOne(ctx, bson.M{ + "_id": card.ID, + }, bson.M{ + "$addToSet": bson.M{ + "assignees": assignee.ID, + }, + }) + + if err != nil { + return UnexpectedMongoError{err} + } + if stats.ModifiedCount == 0 { + return NothingDoneError{} + } + + activity := newActivityCardJoinAssignee(user.ID, assignee.Username, assignee.ID, card.BoardID, card.ListID, card.ID, card.SwimlaneID) + _, err = wekan.insertActivity(ctx, activity) + if err != nil { + return UnexpectedMongoError{err: err} + } + + return nil +} + func (wekan *Wekan) AddMemberToCard(ctx context.Context, card Card, user User, member User) error { if err := wekan.AssertPrivileged(ctx); err != nil { return err diff --git a/users_integration_test.go b/users_integration_test.go index 6285f09..ae4d968 100644 --- a/users_integration_test.go +++ b/users_integration_test.go @@ -262,6 +262,60 @@ func TestUsers_EnsureMemberOutOfCard(t *testing.T) { ass.NotContains(actualCard.Members, member.ID) } +func TestUsers_EnsureAssigneeOutOfCard(t *testing.T) { + ass := assert.New(t) + // GIVEN + board, swimlanes, lists := createTestBoard(t, "", 1, 1) + user := createTestUser(t, "User") + assignee := createTestUser(t, "assignee") + card := createTestCard(t, user.ID, &board.ID, &(swimlanes[0].ID), &(lists[0].ID)) + err := wekan.AddMemberToBoard(ctx, board.ID, BoardMember{UserID: assignee.ID, IsActive: true}) + ass.NoError(err) + + err = wekan.AddAssigneeToCard(ctx, card, assignee, assignee) + ass.NoError(err) + + // WHEN + modified, err := wekan.EnsureAssigneeOutOfCard(ctx, card, assignee, assignee) + ass.Nil(err) + activities, err := wekan.SelectActivitiesFromCardID(ctx, card.ID) + ass.Nil(err) + + // THEN + ass.Len(activities, 3) + ass.True(modified) + ass.Nil(err) + actualCard, err := card.ID.GetDocument(ctx, &wekan) + ass.NotContains(actualCard.Members, assignee.ID) +} + +func TestUsers_EnsureAssigneeOutOfCard_WhenAssigneesPropertyExists(t *testing.T) { + ass := assert.New(t) + // GIVEN + board, swimlanes, lists := createTestBoard(t, "", 1, 1) + user := createTestUser(t, "User") + assignee := createTestUser(t, "assignee") + card := createTestCard(t, user.ID, &board.ID, &(swimlanes[0].ID), &(lists[0].ID)) + err := wekan.AddMemberToBoard(ctx, board.ID, BoardMember{UserID: assignee.ID, IsActive: true}) + ass.NoError(err) + err = wekan.AddAssigneeToCard(ctx, card, assignee, assignee) + ass.NoError(err) + _, err = wekan.EnsureAssigneeOutOfCard(ctx, card, assignee, assignee) + ass.NoError(err) + + // WHEN + err = wekan.AddAssigneeToCard(ctx, card, assignee, assignee) + ass.NoError(err) + activities, err := wekan.SelectActivitiesFromCardID(ctx, card.ID) + ass.Nil(err) + + // THEN + ass.Len(activities, 4) + ass.Nil(err) + actualCard, err := card.ID.GetDocument(ctx, &wekan) + ass.NotContains(actualCard.Members, assignee.ID) +} + func TestUsers_EnsureMemberOutOfCard_WhenUserIsNotBoardMember(t *testing.T) { ass := assert.New(t) // GIVEN