diff --git a/scnserver/api/apierr/enums.go b/scnserver/api/apierr/enums.go index 9d1d448..fb2f7ec 100644 --- a/scnserver/api/apierr/enums.go +++ b/scnserver/api/apierr/enums.go @@ -29,7 +29,7 @@ const ( SENDERNAME_TOO_LONG APIError = 1206 CHANNEL_TOO_LONG APIError = 1207 CHANNEL_DESCRIPTION_TOO_LONG APIError = 1208 - CHANNEL_NAME_WOULD_CHANGE APIError = 1251 + CHANNEL_NAME_EMPTY APIError = 1209 USER_NOT_FOUND APIError = 1301 CLIENT_NOT_FOUND APIError = 1302 diff --git a/scnserver/api/handler/api.go b/scnserver/api/handler/api.go index 01d598f..e286b27 100644 --- a/scnserver/api/handler/api.go +++ b/scnserver/api/handler/api.go @@ -678,9 +678,15 @@ func (h APIHandler) CreateChannel(g *gin.Context) ginresp.HTTPResponse { if len(channelDisplayName) > user.MaxChannelNameLength() { return ginresp.APIError(g, 400, apierr.CHANNEL_TOO_LONG, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil) } + if len(strings.TrimSpace(channelDisplayName)) == 0 { + return ginresp.APIError(g, 400, apierr.CHANNEL_NAME_EMPTY, fmt.Sprintf("Channel displayname cannot be empty"), nil) + } if len(channelInternalName) > user.MaxChannelNameLength() { return ginresp.APIError(g, 400, apierr.CHANNEL_TOO_LONG, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil) } + if len(strings.TrimSpace(channelInternalName)) == 0 { + return ginresp.APIError(g, 400, apierr.CHANNEL_NAME_EMPTY, fmt.Sprintf("Channel internalname cannot be empty"), nil) + } if channelExisting != nil { return ginresp.APIError(g, 409, apierr.CHANNEL_ALREADY_EXISTS, "Channel with this name already exists", nil) @@ -753,7 +759,7 @@ func (h APIHandler) UpdateChannel(g *gin.Context) ginresp.HTTPResponse { return *permResp } - oldChannel, err := h.database.GetChannel(ctx, u.UserID, u.ChannelID, true) + _, err := h.database.GetChannel(ctx, u.UserID, u.ChannelID, true) if err == sql.ErrNoRows { return ginresp.APIError(g, 404, apierr.CHANNEL_NOT_FOUND, "Channel not found", err) } @@ -781,16 +787,15 @@ func (h APIHandler) UpdateChannel(g *gin.Context) ginresp.HTTPResponse { if b.DisplayName != nil { newDisplayName := h.app.NormalizeChannelDisplayName(*b.DisplayName) - newInternalName := h.app.NormalizeChannelInternalName(*b.DisplayName) - - if newInternalName != oldChannel.InternalName { - return ginresp.APIError(g, 400, apierr.CHANNEL_NAME_WOULD_CHANGE, "Cannot substantially change the channel name", err) - } if len(newDisplayName) > user.MaxChannelNameLength() { return ginresp.APIError(g, 400, apierr.CHANNEL_TOO_LONG, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil) } + if len(strings.TrimSpace(newDisplayName)) == 0 { + return ginresp.APIError(g, 400, apierr.CHANNEL_NAME_EMPTY, fmt.Sprintf("Channel displayname cannot be empty"), nil) + } + err := h.database.UpdateChannelDisplayName(ctx, u.ChannelID, newDisplayName) if err != nil { return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to update channel", err) diff --git a/scnserver/api/handler/message.go b/scnserver/api/handler/message.go index a8aa226..4916969 100644 --- a/scnserver/api/handler/message.go +++ b/scnserver/api/handler/message.go @@ -176,9 +176,15 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex if len(channelDisplayName) > user.MaxChannelNameLength() { return nil, langext.Ptr(ginresp.SendAPIError(g, 400, apierr.CHANNEL_TOO_LONG, hl.CHANNEL, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil)) } + if len(strings.TrimSpace(channelDisplayName)) == 0 { + return nil, langext.Ptr(ginresp.SendAPIError(g, 400, apierr.CHANNEL_NAME_EMPTY, hl.CHANNEL, fmt.Sprintf("Channel displayname cannot be empty"), nil)) + } if len(channelInternalName) > user.MaxChannelNameLength() { return nil, langext.Ptr(ginresp.SendAPIError(g, 400, apierr.CHANNEL_TOO_LONG, hl.CHANNEL, fmt.Sprintf("Channel too long (max %d characters)", user.MaxChannelNameLength()), nil)) } + if len(strings.TrimSpace(channelInternalName)) == 0 { + return nil, langext.Ptr(ginresp.SendAPIError(g, 400, apierr.CHANNEL_NAME_EMPTY, hl.CHANNEL, fmt.Sprintf("Channel internalname cannot be empty"), nil)) + } if SenderName != nil && len(*SenderName) > user.MaxSenderName() { return nil, langext.Ptr(ginresp.SendAPIError(g, 400, apierr.SENDERNAME_TOO_LONG, hl.SENDER_NAME, fmt.Sprintf("SenderName too long (max %d characters)", user.MaxSenderName()), nil)) } diff --git a/scnserver/logic/application.go b/scnserver/logic/application.go index a032ac1..74a6525 100644 --- a/scnserver/logic/application.go +++ b/scnserver/logic/application.go @@ -328,27 +328,15 @@ func (app *Application) GetOrCreateChannel(ctx *AppContext, userid models.UserID } func (app *Application) NormalizeChannelDisplayName(v string) string { - v = strings.TrimSpace(v) - v = rexWhitespaceStart.RemoveAll(v) - v = rexWhitespaceEnd.RemoveAll(v) - - return v + return strings.TrimSpace(v) } func (app *Application) NormalizeChannelInternalName(v string) string { - v = strings.TrimSpace(v) - v = strings.ToLower(v) - v = rexWhitespaceStart.RemoveAll(v) - v = rexWhitespaceEnd.RemoveAll(v) - - return v + return strings.TrimSpace(v) } func (app *Application) NormalizeUsername(v string) string { - v = strings.TrimSpace(v) - v = rexNormalizeUsername.RemoveAll(v) - - return v + return strings.TrimSpace(v) } func (app *Application) DeliverMessage(ctx context.Context, client models.Client, msg models.Message, compatTitleOverride *string) (*string, error) { diff --git a/scnserver/test/channel_test.go b/scnserver/test/channel_test.go index adfd8eb..175f4c8 100644 --- a/scnserver/test/channel_test.go +++ b/scnserver/test/channel_test.go @@ -100,43 +100,23 @@ func TestChannelNameNormalization(t *testing.T) { } tt.RequestAuthPost[gin.H](t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": "tESt", + "name": "TeST-99", }) { clist := tt.RequestAuthGet[chanlist](t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid)) - tt.AssertMappedSet(t, "channels", []string{"tESt"}, clist.Channels, "display_name") - tt.AssertMappedSet(t, "channels", []string{"test"}, clist.Channels, "internal_name") + tt.AssertMappedSet(t, "channels", []string{"TeST-99"}, clist.Channels, "display_name") + tt.AssertMappedSet(t, "channels", []string{"TeST-99"}, clist.Channels, "internal_name") } tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": "test", - }, 409, apierr.CHANNEL_ALREADY_EXISTS) - - tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": "TEST", - }, 409, apierr.CHANNEL_ALREADY_EXISTS) - - tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": "Test", - }, 409, apierr.CHANNEL_ALREADY_EXISTS) - - tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": "Test ", - }, 409, apierr.CHANNEL_ALREADY_EXISTS) - - tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": " Test", - }, 409, apierr.CHANNEL_ALREADY_EXISTS) - - tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ - "name": "\rTeSt\n", + "name": "TeST-99", }, 409, apierr.CHANNEL_ALREADY_EXISTS) { clist := tt.RequestAuthGet[chanlist](t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid)) - tt.AssertMappedSet(t, "channels", []string{"tESt"}, clist.Channels, "display_name") - tt.AssertMappedSet(t, "channels", []string{"test"}, clist.Channels, "internal_name") + tt.AssertMappedSet(t, "channels", []string{"TeST-99"}, clist.Channels, "display_name") + tt.AssertMappedSet(t, "channels", []string{"TeST-99"}, clist.Channels, "internal_name") } tt.RequestAuthPost[gin.H](t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{ @@ -145,8 +125,8 @@ func TestChannelNameNormalization(t *testing.T) { { clist := tt.RequestAuthGet[chanlist](t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid)) - tt.AssertMappedSet(t, "channels", []string{"tESt", "WeiRD_[\uF5FF]\\stUFf"}, clist.Channels, "display_name") - tt.AssertMappedSet(t, "channels", []string{"test", "weird_[\uF5FF]\\stuff"}, clist.Channels, "internal_name") + tt.AssertMappedSet(t, "channels", []string{"TeST-99", "WeiRD_[\uF5FF]\\stUFf"}, clist.Channels, "display_name") + tt.AssertMappedSet(t, "channels", []string{"TeST-99", "WeiRD_[\uF5FF]\\stUFf"}, clist.Channels, "internal_name") } } @@ -162,18 +142,18 @@ func TestListChannelsDefault(t *testing.T) { } testdata := map[int][]string{ - 0: {"main", "chatting chamber", "unicôdé häll \U0001f92a", "promotions", "reminders"}, + 0: {"main", "Chatting Chamber", "Unicôdé Häll \U0001f92a", "Promotions", "Reminders"}, 1: {"main", "private"}, - 2: {"main", "ü", "ö", "ä"}, - 3: {"main", "\U0001f5ff", "innovations", "reminders"}, + 2: {"main", "Ü", "Ö", "Ä"}, + 3: {"main", "\U0001f5ff", "Innovations", "Reminders"}, 4: {"main"}, - 5: {"main", "test1", "test2", "test3", "test4", "test5"}, - 6: {"main", "security", "lipsum"}, + 5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"}, + 6: {"main", "Security", "Lipsum"}, 7: {"main"}, 8: {"main"}, 9: {"main", "manual@chan"}, 10: {"main"}, - 11: {"promotions"}, + 11: {"Promotions"}, 12: {}, 13: {}, 14: {"main", "chan_self_subscribed", "chan_self_unsub"}, @@ -197,18 +177,18 @@ func TestListChannelsOwned(t *testing.T) { } testdata := map[int][]string{ - 0: {"main", "chatting chamber", "unicôdé häll \U0001f92a", "promotions", "reminders"}, + 0: {"main", "Chatting Chamber", "Unicôdé Häll \U0001f92a", "Promotions", "Reminders"}, 1: {"main", "private"}, - 2: {"main", "ü", "ö", "ä"}, - 3: {"main", "\U0001f5ff", "innovations", "reminders"}, + 2: {"main", "Ü", "Ö", "Ä"}, + 3: {"main", "\U0001f5ff", "Innovations", "Reminders"}, 4: {"main"}, - 5: {"main", "test1", "test2", "test3", "test4", "test5"}, - 6: {"main", "security", "lipsum"}, + 5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"}, + 6: {"main", "Security", "Lipsum"}, 7: {"main"}, 8: {"main"}, 9: {"main", "manual@chan"}, 10: {"main"}, - 11: {"promotions"}, + 11: {"Promotions"}, 12: {}, 13: {}, 14: {"main", "chan_self_subscribed", "chan_self_unsub"}, @@ -232,18 +212,18 @@ func TestListChannelsSubscribedAny(t *testing.T) { } testdata := map[int][]string{ - 0: {"main", "chatting chamber", "unicôdé häll \U0001f92a", "promotions", "reminders"}, + 0: {"main", "Chatting Chamber", "Unicôdé Häll \U0001f92a", "Promotions", "Reminders"}, 1: {"main", "private"}, - 2: {"main", "ü", "ö", "ä"}, - 3: {"main", "\U0001f5ff", "innovations", "reminders"}, + 2: {"main", "Ü", "Ö", "Ä"}, + 3: {"main", "\U0001f5ff", "Innovations", "Reminders"}, 4: {"main"}, - 5: {"main", "test1", "test2", "test3", "test4", "test5"}, - 6: {"main", "security", "lipsum"}, + 5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"}, + 6: {"main", "Security", "Lipsum"}, 7: {"main"}, 8: {"main"}, 9: {"main", "manual@chan"}, 10: {"main"}, - 11: {"promotions"}, + 11: {"Promotions"}, 12: {}, 13: {}, 14: {"main", "chan_self_subscribed", "chan_other_request", "chan_other_accepted"}, @@ -267,18 +247,18 @@ func TestListChannelsAllAny(t *testing.T) { } testdata := map[int][]string{ - 0: {"main", "chatting chamber", "unicôdé häll \U0001f92a", "promotions", "reminders"}, + 0: {"main", "Chatting Chamber", "Unicôdé Häll \U0001f92a", "Promotions", "Reminders"}, 1: {"main", "private"}, - 2: {"main", "ü", "ö", "ä"}, - 3: {"main", "\U0001f5ff", "innovations", "reminders"}, + 2: {"main", "Ü", "Ö", "Ä"}, + 3: {"main", "\U0001f5ff", "Innovations", "Reminders"}, 4: {"main"}, - 5: {"main", "test1", "test2", "test3", "test4", "test5"}, - 6: {"main", "security", "lipsum"}, + 5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"}, + 6: {"main", "Security", "Lipsum"}, 7: {"main"}, 8: {"main"}, 9: {"main", "manual@chan"}, 10: {"main"}, - 11: {"promotions"}, + 11: {"Promotions"}, 12: {}, 13: {}, 14: {"main", "chan_self_subscribed", "chan_self_unsub", "chan_other_request", "chan_other_accepted"}, @@ -302,18 +282,18 @@ func TestListChannelsSubscribed(t *testing.T) { } testdata := map[int][]string{ - 0: {"main", "chatting chamber", "unicôdé häll \U0001f92a", "promotions", "reminders"}, + 0: {"main", "Chatting Chamber", "Unicôdé Häll \U0001f92a", "Promotions", "Reminders"}, 1: {"main", "private"}, - 2: {"main", "ü", "ö", "ä"}, - 3: {"main", "\U0001f5ff", "innovations", "reminders"}, + 2: {"main", "Ü", "Ö", "Ä"}, + 3: {"main", "\U0001f5ff", "Innovations", "Reminders"}, 4: {"main"}, - 5: {"main", "test1", "test2", "test3", "test4", "test5"}, - 6: {"main", "security", "lipsum"}, + 5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"}, + 6: {"main", "Security", "Lipsum"}, 7: {"main"}, 8: {"main"}, 9: {"main", "manual@chan"}, 10: {"main"}, - 11: {"promotions"}, + 11: {"Promotions"}, 12: {}, 13: {}, 14: {"main", "chan_self_subscribed", "chan_other_accepted"}, @@ -337,18 +317,18 @@ func TestListChannelsAll(t *testing.T) { } testdata := map[int][]string{ - 0: {"main", "chatting chamber", "unicôdé häll \U0001f92a", "promotions", "reminders"}, + 0: {"main", "Chatting Chamber", "Unicôdé Häll \U0001f92a", "Promotions", "Reminders"}, 1: {"main", "private"}, - 2: {"main", "ü", "ö", "ä"}, - 3: {"main", "\U0001f5ff", "innovations", "reminders"}, + 2: {"main", "Ü", "Ö", "Ä"}, + 3: {"main", "\U0001f5ff", "Innovations", "Reminders"}, 4: {"main"}, - 5: {"main", "test1", "test2", "test3", "test4", "test5"}, - 6: {"main", "security", "lipsum"}, + 5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"}, + 6: {"main", "Security", "Lipsum"}, 7: {"main"}, 8: {"main"}, 9: {"main", "manual@chan"}, 10: {"main"}, - 11: {"promotions"}, + 11: {"Promotions"}, 12: {}, 13: {}, 14: {"main", "chan_self_subscribed", "chan_self_unsub", "chan_other_accepted"}, @@ -424,8 +404,8 @@ func TestChannelUpdate(t *testing.T) { // [2] fail to update display_name tt.RequestAuthPatchShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", uid, chanid), gin.H{ - "display_name": "SERVER-ALERTS2", - }, 400, apierr.CHANNEL_NAME_WOULD_CHANGE) + "display_name": "", + }, 400, apierr.CHANNEL_NAME_EMPTY) // [3] renew subscribe_key @@ -534,9 +514,9 @@ func TestListChannelMessages(t *testing.T) { clist := tt.RequestAuthGet[chanlist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.User[16].UID)) - chan1 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "chan1" }).ChannelId - chan2 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "chan2" }).ChannelId - chan3 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "chan3" }).ChannelId + chan1 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "Chan1" }).ChannelId + chan2 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "Chan2" }).ChannelId + chan3 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "Chan3" }).ChannelId { msgList0 := tt.RequestAuthGet[mglist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/messages", data.User[16].UID, chan1)) @@ -614,22 +594,22 @@ func TestListSubscribedChannelMessages(t *testing.T) { clist := tt.RequestAuthGet[chanlist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.User[16].UID)) - chan1 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "chan1" }) - chan2 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "chan2" }) - chan3 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "chan3" }) + chan1 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "Chan1" }) + chan2 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "Chan2" }) + chan3 := langext.ArrFirstOrNil(clist.Channels, func(v chanobj) bool { return v.InternalName == "Chan3" }) { sub1 := tt.RequestAuthPost[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[1].UID, chan1.SubscribeKey), gin.H{ "channel_owner_user_id": data.User[16].UID, - "channel_internal_name": "chan1", + "channel_internal_name": "Chan1", }) sub2 := tt.RequestAuthPost[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[1].UID, chan2.SubscribeKey), gin.H{ "channel_owner_user_id": data.User[16].UID, - "channel_internal_name": "chan2", + "channel_internal_name": "Chan2", }) sub3 := tt.RequestAuthPost[gin.H](t, data.User[1].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[1].UID, chan3.SubscribeKey), gin.H{ "channel_owner_user_id": data.User[16].UID, - "channel_internal_name": "chan3", + "channel_internal_name": "Chan3", }) tt.RequestAuthPatch[gin.H](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, sub1["subscription_id"]), gin.H{ @@ -751,13 +731,13 @@ func TestListChannelSubscriptions(t *testing.T) { 0, 0, 0) chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan1", + "name": "Chan1", }) chan2 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan2", + "name": "Chan2", }) chan3 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan3", + "name": "Chan3", }) countBoth( @@ -768,14 +748,14 @@ func TestListChannelSubscriptions(t *testing.T) { sub1 := tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UserID, chan1.SubscribeKey), gin.H{ "channel_owner_user_id": data2.UserID, - "channel_internal_name": "chan1", + "channel_internal_name": "Chan1", }) sub2 := tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UserID, chan2.SubscribeKey), gin.H{ "channel_id": chan2.ChannelId, }) sub3 := tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UserID, chan3.SubscribeKey), gin.H{ "channel_owner_user_id": data2.UserID, - "channel_internal_name": "chan3", + "channel_internal_name": "Chan3", }) countBoth( @@ -904,7 +884,7 @@ func TestListChannelMessagesOfUnsubscribed(t *testing.T) { } chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan1", + "name": "Chan1", }) tt.RequestAuthGetShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/messages", data1.UserID, chan1.ChannelId), 401, apierr.USER_AUTH_FAILED) @@ -964,12 +944,12 @@ func TestListChannelMessagesOfUnconfirmed1(t *testing.T) { } chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan1", + "name": "Chan1", }) tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UserID, chan1.SubscribeKey), gin.H{ "channel_owner_user_id": data2.UserID, - "channel_internal_name": "chan1", + "channel_internal_name": "Chan1", }) tt.RequestAuthGetShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/messages", data1.UserID, chan1.ChannelId), 401, apierr.USER_AUTH_FAILED) @@ -1029,7 +1009,7 @@ func TestListChannelMessagesOfUnconfirmed2(t *testing.T) { } chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan1", + "name": "Chan1", }) tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UserID, chan1.SubscribeKey), gin.H{ @@ -1093,7 +1073,7 @@ func TestListChannelMessagesOfRevokedConfirmation(t *testing.T) { } chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{ - "name": "chan1", + "name": "Chan1", }) sub1 := tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UserID, chan1.SubscribeKey), gin.H{ diff --git a/scnserver/test/util/common.go b/scnserver/test/util/common.go index 0c12a36..e1b7f6c 100644 --- a/scnserver/test/util/common.go +++ b/scnserver/test/util/common.go @@ -1,6 +1,7 @@ package util import ( + "encoding/json" "fmt" "github.com/gin-gonic/gin" "gogs.mikescher.com/BlackForestBytes/goext/langext" @@ -328,8 +329,8 @@ func AssertMappedSet[T langext.OrderedConstraint](t *testing.T, key string, expe if !langext.ArrEqualsExact(actual, expected) { t.Errorf("Value [%s] differs (%T <-> %T):\n", key, expected, actual) - t.Errorf("Actual := [%v]\n", actual) - t.Errorf("Expected := [%v]\n", expected) + t.Errorf("Actual := [%v]\n", ljson(actual)) + t.Errorf("Expected := [%v]\n", ljson(expected)) t.Error(string(debug.Stack())) @@ -364,3 +365,8 @@ func IsWholeFloat[T langext.FloatConstraint](v T) bool { _, frac := math.Modf(math.Abs(float64(v))) return frac == 0.0 } + +func ljson(v any) string { + b, _ := json.Marshal(v) + return string(b) +}