fix: link group invitations to join requests

This commit is contained in:
richjohnrambo
2026-09-11 17:26:05 +08:00
parent 367bed2940
commit cfab33f45a
3 changed files with 138 additions and 7 deletions
+91
View File
@@ -426,6 +426,23 @@ func (s *testGroupBusinessStore) UpdateMember(_ types.TenantID, topic string, ui
func (s *testGroupBusinessStore) CreateInvitation(_ types.TenantID, inv *types.GroupInvitation) (*types.GroupInvitation, error) {
s.invitations = append(s.invitations, *inv)
if inv.JoinRequestID != "" {
expiresAt := inv.ExpiresAt
s.joinRequests = append(s.joinRequests, types.GroupJoinRequest{
RequestID: inv.JoinRequestID,
Topic: inv.Topic,
ApplicantUserID: inv.TargetUserID,
InviterUserID: inv.InviterUserID,
Source: "invitation",
Message: inv.Message,
Status: types.GroupJoinRequestStatusPending,
ExpiresAt: &expiresAt,
IdempotencyKey: inv.IdempotencyKey,
Version: 1,
CreatedAt: inv.CreatedAt,
UpdatedAt: inv.UpdatedAt,
})
}
return inv, nil
}
@@ -4722,6 +4739,80 @@ func TestServeIMGroupInvitationAddsNonMember(t *testing.T) {
}
}
func TestServeIMGroupInvitationCreatesApprovalRequest(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockStore := expectIMBearer(t, ctrl, "token-1", 7, 42)
mockStore.EXPECT().GetUidString().Return("invite")
mockStore.EXPECT().GetUidString().Return("request")
oldSubs := store.Subs
oldGroupBusiness := store.GroupBusiness
subs := mock_store.NewMockSubsPersistenceInterface(ctrl)
groupStore := &testGroupBusinessStore{settings: &types.GroupSettings{
Topic: "grpAlpha", OwnerUserID: types.Uid(42), Name: "Alpha", GroupStatus: types.GroupStatusActive,
JoinApproval: true, MemberInvite: true, MaxAdminCount: groupMaxAdminCount, Version: 1,
}}
store.Subs = subs
store.GroupBusiness = groupStore
defer func() {
store.Subs = oldSubs
store.GroupBusiness = oldGroupBusiness
}()
owner := types.Uid(42)
target := types.Uid(43)
ownerSub := &types.Subscription{
TenantID: 7, User: owner.String(), Topic: "grpAlpha", ModeWant: types.ModeCFull, ModeGiven: types.ModeCFull,
}
subs.EXPECT().Get(types.TenantID(7), "grpAlpha", owner, false).Return(ownerSub, nil).Times(3)
subs.EXPECT().Get(types.TenantID(7), "grpAlpha", target, false).Return(nil, types.ErrNotFound)
req := httptest.NewRequest(http.MethodPost, "/v1/im/groups/grpAlpha/invitations",
bytes.NewBufferString(`{"user_ids":["`+target.UserId()+`"],"message":"welcome"}`))
req.Header.Set("Authorization", "Bearer token-1")
req.Header.Set("Idempotency-Key", "invite-1")
rec := httptest.NewRecorder()
serveIMGroupResource(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status: got %d body=%s", rec.Code, rec.Body.String())
}
data := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
items := data["items"].([]any)
item := items[0].(map[string]any)
if item["invitation_id"] != "ginv_invite" || item["join_request_id"] != "gjr_request" || item["status"] != types.GroupInvitationStatusPending {
t.Fatalf("unexpected invitation response: %#v", data)
}
if len(groupStore.joinRequests) != 1 || groupStore.joinRequests[0].RequestID != "gjr_request" ||
groupStore.joinRequests[0].ApplicantUserID != target || groupStore.joinRequests[0].Source != "invitation" {
t.Fatalf("join request was not created: %#v", groupStore.joinRequests)
}
req = httptest.NewRequest(http.MethodGet, "/v1/im/groups/grpAlpha/summary", nil)
req.Header.Set("Authorization", "Bearer token-1")
rec = httptest.NewRecorder()
serveIMGroupResource(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("summary status: got %d body=%s", rec.Code, rec.Body.String())
}
summary := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
if summary["pending_join_request_count"] != float64(1) {
t.Fatalf("unexpected summary response: %#v", summary)
}
req = httptest.NewRequest(http.MethodGet, "/v1/im/groups/grpAlpha/join-requests?status=pending", nil)
req.Header.Set("Authorization", "Bearer token-1")
rec = httptest.NewRecorder()
serveIMGroupResource(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("join requests status: got %d body=%s", rec.Code, rec.Body.String())
}
list := decodeIMHTTPResponse(t, rec).Data.(map[string]any)
requests := list["items"].([]any)
if len(requests) != 1 || requests[0].(map[string]any)["request_id"] != "gjr_request" {
t.Fatalf("unexpected join requests response: %#v", list)
}
}
func TestServeIMGroupInvitationAccept(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()