Fix IM report and group permission regressions

This commit is contained in:
richjohnrambo
2026-09-02 10:01:38 +08:00
parent 15a4174ed1
commit ac45223e39
5 changed files with 299 additions and 39 deletions
+73 -5
View File
@@ -333,6 +333,7 @@ type testGroupBusinessStore struct {
invitations []types.GroupInvitation
updatedSettings types.GroupSettingsPatch
updatedMembers []types.GroupMemberPatch
updatedRoleMode types.AccessMode
}
func (s *testGroupBusinessStore) CreateGroup(_ types.TenantID, _ *types.Topic, _ types.Uid, _ any,
@@ -517,8 +518,9 @@ func (s *testGroupBusinessStore) Leave(_ types.TenantID, _ string, _ types.Uid,
}
func (s *testGroupBusinessStore) UpdateRole(_ types.TenantID, topic string, _ types.Uid, target types.Uid,
role string, _ types.AccessMode, _ time.Time) error {
role string, mode types.AccessMode, _ time.Time) error {
s.updatedMembers = append(s.updatedMembers, types.GroupMemberPatch{Role: &role})
s.updatedRoleMode = mode
s.member = &types.GroupMember{Topic: topic, UserID: target, Role: role, MemberStatus: types.GroupMemberStatusActive}
return nil
}
@@ -3692,7 +3694,8 @@ func TestServeIMGroupDetailPatchSettingsProfileAndLeave(t *testing.T) {
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
store.Topics = topics
store.Subs = subs
store.GroupBusiness = &testGroupBusinessStore{}
groupStore := &testGroupBusinessStore{}
store.GroupBusiness = groupStore
defer func() {
store.Store = oldStore
store.Topics = oldTopics
@@ -3771,7 +3774,8 @@ func TestServeIMGroupLeave(t *testing.T) {
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
store.Topics = topics
store.Subs = subs
store.GroupBusiness = &testGroupBusinessStore{}
groupStore := &testGroupBusinessStore{}
store.GroupBusiness = groupStore
defer func() {
store.Topics = oldTopics
store.Subs = oldSubs
@@ -4020,7 +4024,8 @@ func TestServeIMGroupAnnouncementGovernanceJoinRequest(t *testing.T) {
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
store.Topics = topics
store.Subs = subs
store.GroupBusiness = &testGroupBusinessStore{}
groupStore := &testGroupBusinessStore{}
store.GroupBusiness = groupStore
defer func() {
store.Store = oldStore
store.Topics = oldTopics
@@ -4083,7 +4088,8 @@ func TestServeIMGroupAdminsMutesAndOwnerTransfer(t *testing.T) {
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
store.Topics = topics
store.Subs = subs
store.GroupBusiness = &testGroupBusinessStore{}
groupStore := &testGroupBusinessStore{}
store.GroupBusiness = groupStore
defer func() {
store.Store = oldStore
store.Topics = oldTopics
@@ -4106,6 +4112,9 @@ func TestServeIMGroupAdminsMutesAndOwnerTransfer(t *testing.T) {
if adminRec.Code != http.StatusOK {
t.Fatalf("admin status: got %d body=%s", adminRec.Code, adminRec.Body.String())
}
if !groupStore.updatedRoleMode.IsAdmin() || groupStore.updatedRoleMode.IsOwner() {
t.Fatalf("admin role mode should grant admin without owner: %s", groupStore.updatedRoleMode.String())
}
muteReq := httptest.NewRequest(http.MethodPost, "/v1/im/groups/grpAlpha/mutes", bytes.NewBufferString(`{"members":[{"user_id":"`+target.UserId()+`"}],"reason":"test"}`))
muteReq.Header.Set("Authorization", "Bearer token-1")
@@ -5165,6 +5174,65 @@ func TestServeIMMessageRecall(t *testing.T) {
}
}
func TestServeIMMessageRecallNormalizesP2PUserTopic(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
actor := types.Uid(42)
peer := types.Uid(43)
normalizedTopic := actor.P2PName(peer)
expectIMBearer(t, ctrl, "token-1", 7, actor)
oldSubs := store.Subs
oldMessages := store.Messages
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
messages := mock_store.NewMockMessagesPersistenceInterface(ctrl)
store.Subs = subs
store.Messages = messages
defer func() {
store.Subs = oldSubs
store.Messages = oldMessages
}()
subs.EXPECT().Get(types.TenantID(7), normalizedTopic, actor, false).Return(&types.Subscription{
TenantID: 7,
User: actor.String(),
Topic: normalizedTopic,
ModeWant: types.ModeCPublic,
ModeGiven: types.ModeCPublic,
}, nil)
messages.EXPECT().GetOne(types.TenantID(7), normalizedTopic, int64(9)).Return(&types.Message{
TenantID: 7,
SeqId: 9,
Topic: normalizedTopic,
From: actor.String(),
Version: 1,
ObjHeader: types.ObjHeader{CreatedAt: time.Now().Add(-time.Second)},
}, nil)
messages.EXPECT().Recall(types.TenantID(7), normalizedTopic, int64(9), actor, 1, gomock.Any()).Return(&types.Message{
TenantID: 7,
SeqId: 9,
Topic: normalizedTopic,
From: actor.String(),
Version: 2,
RecalledAt: ptrTime(time.Now().UTC()),
RecalledBy: actor.String(),
ObjHeader: types.ObjHeader{UpdatedAt: time.Now().UTC()},
}, nil)
req := httptest.NewRequest(http.MethodPost, "/v1/im/topics/"+peer.UserId()+"/messages/9/recall", bytes.NewBufferString(`{"version":1}`))
req.Header.Set("Authorization", "Bearer token-1")
rec := httptest.NewRecorder()
serveIMMessageRecall(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status: got %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String())
}
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
if data["topic"] != normalizedTopic {
t.Fatalf("expected normalized topic %q, got %#v", normalizedTopic, data)
}
}
func TestServeIMMessageRevision(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()