Remove Channel/Username normalization (except TrimSpace)
This commit is contained in:
parent
efaad3f97c
commit
397bfe78aa
@ -29,7 +29,7 @@ const (
|
|||||||
SENDERNAME_TOO_LONG APIError = 1206
|
SENDERNAME_TOO_LONG APIError = 1206
|
||||||
CHANNEL_TOO_LONG APIError = 1207
|
CHANNEL_TOO_LONG APIError = 1207
|
||||||
CHANNEL_DESCRIPTION_TOO_LONG APIError = 1208
|
CHANNEL_DESCRIPTION_TOO_LONG APIError = 1208
|
||||||
CHANNEL_NAME_WOULD_CHANGE APIError = 1251
|
CHANNEL_NAME_EMPTY APIError = 1209
|
||||||
|
|
||||||
USER_NOT_FOUND APIError = 1301
|
USER_NOT_FOUND APIError = 1301
|
||||||
CLIENT_NOT_FOUND APIError = 1302
|
CLIENT_NOT_FOUND APIError = 1302
|
||||||
|
@ -678,9 +678,15 @@ func (h APIHandler) CreateChannel(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
if len(channelDisplayName) > user.MaxChannelNameLength() {
|
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)
|
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() {
|
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)
|
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 {
|
if channelExisting != nil {
|
||||||
return ginresp.APIError(g, 409, apierr.CHANNEL_ALREADY_EXISTS, "Channel with this name already exists", 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
|
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 {
|
if err == sql.ErrNoRows {
|
||||||
return ginresp.APIError(g, 404, apierr.CHANNEL_NOT_FOUND, "Channel not found", err)
|
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 {
|
if b.DisplayName != nil {
|
||||||
|
|
||||||
newDisplayName := h.app.NormalizeChannelDisplayName(*b.DisplayName)
|
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() {
|
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)
|
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)
|
err := h.database.UpdateChannelDisplayName(ctx, u.ChannelID, newDisplayName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to update channel", err)
|
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to update channel", err)
|
||||||
|
@ -176,9 +176,15 @@ func (h MessageHandler) sendMessageInternal(g *gin.Context, ctx *logic.AppContex
|
|||||||
if len(channelDisplayName) > user.MaxChannelNameLength() {
|
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))
|
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() {
|
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))
|
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() {
|
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))
|
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))
|
||||||
}
|
}
|
||||||
|
@ -328,27 +328,15 @@ func (app *Application) GetOrCreateChannel(ctx *AppContext, userid models.UserID
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) NormalizeChannelDisplayName(v string) string {
|
func (app *Application) NormalizeChannelDisplayName(v string) string {
|
||||||
v = strings.TrimSpace(v)
|
return strings.TrimSpace(v)
|
||||||
v = rexWhitespaceStart.RemoveAll(v)
|
|
||||||
v = rexWhitespaceEnd.RemoveAll(v)
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) NormalizeChannelInternalName(v string) string {
|
func (app *Application) NormalizeChannelInternalName(v string) string {
|
||||||
v = strings.TrimSpace(v)
|
return strings.TrimSpace(v)
|
||||||
v = strings.ToLower(v)
|
|
||||||
v = rexWhitespaceStart.RemoveAll(v)
|
|
||||||
v = rexWhitespaceEnd.RemoveAll(v)
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) NormalizeUsername(v string) string {
|
func (app *Application) NormalizeUsername(v string) string {
|
||||||
v = strings.TrimSpace(v)
|
return strings.TrimSpace(v)
|
||||||
v = rexNormalizeUsername.RemoveAll(v)
|
|
||||||
|
|
||||||
return v
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *Application) DeliverMessage(ctx context.Context, client models.Client, msg models.Message, compatTitleOverride *string) (*string, error) {
|
func (app *Application) DeliverMessage(ctx context.Context, client models.Client, msg models.Message, compatTitleOverride *string) (*string, error) {
|
||||||
|
@ -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{
|
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))
|
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-99"}, clist.Channels, "display_name")
|
||||||
tt.AssertMappedSet(t, "channels", []string{"test"}, clist.Channels, "internal_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{
|
tt.RequestAuthPostShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid), gin.H{
|
||||||
"name": "test",
|
"name": "TeST-99",
|
||||||
}, 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",
|
|
||||||
}, 409, apierr.CHANNEL_ALREADY_EXISTS)
|
}, 409, apierr.CHANNEL_ALREADY_EXISTS)
|
||||||
|
|
||||||
{
|
{
|
||||||
clist := tt.RequestAuthGet[chanlist](t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", uid))
|
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-99"}, clist.Channels, "display_name")
|
||||||
tt.AssertMappedSet(t, "channels", []string{"test"}, clist.Channels, "internal_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{
|
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))
|
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-99", "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, "internal_name")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -162,18 +142,18 @@ func TestListChannelsDefault(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testdata := map[int][]string{
|
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"},
|
1: {"main", "private"},
|
||||||
2: {"main", "ü", "ö", "ä"},
|
2: {"main", "Ü", "Ö", "Ä"},
|
||||||
3: {"main", "\U0001f5ff", "innovations", "reminders"},
|
3: {"main", "\U0001f5ff", "Innovations", "Reminders"},
|
||||||
4: {"main"},
|
4: {"main"},
|
||||||
5: {"main", "test1", "test2", "test3", "test4", "test5"},
|
5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"},
|
||||||
6: {"main", "security", "lipsum"},
|
6: {"main", "Security", "Lipsum"},
|
||||||
7: {"main"},
|
7: {"main"},
|
||||||
8: {"main"},
|
8: {"main"},
|
||||||
9: {"main", "manual@chan"},
|
9: {"main", "manual@chan"},
|
||||||
10: {"main"},
|
10: {"main"},
|
||||||
11: {"promotions"},
|
11: {"Promotions"},
|
||||||
12: {},
|
12: {},
|
||||||
13: {},
|
13: {},
|
||||||
14: {"main", "chan_self_subscribed", "chan_self_unsub"},
|
14: {"main", "chan_self_subscribed", "chan_self_unsub"},
|
||||||
@ -197,18 +177,18 @@ func TestListChannelsOwned(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testdata := map[int][]string{
|
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"},
|
1: {"main", "private"},
|
||||||
2: {"main", "ü", "ö", "ä"},
|
2: {"main", "Ü", "Ö", "Ä"},
|
||||||
3: {"main", "\U0001f5ff", "innovations", "reminders"},
|
3: {"main", "\U0001f5ff", "Innovations", "Reminders"},
|
||||||
4: {"main"},
|
4: {"main"},
|
||||||
5: {"main", "test1", "test2", "test3", "test4", "test5"},
|
5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"},
|
||||||
6: {"main", "security", "lipsum"},
|
6: {"main", "Security", "Lipsum"},
|
||||||
7: {"main"},
|
7: {"main"},
|
||||||
8: {"main"},
|
8: {"main"},
|
||||||
9: {"main", "manual@chan"},
|
9: {"main", "manual@chan"},
|
||||||
10: {"main"},
|
10: {"main"},
|
||||||
11: {"promotions"},
|
11: {"Promotions"},
|
||||||
12: {},
|
12: {},
|
||||||
13: {},
|
13: {},
|
||||||
14: {"main", "chan_self_subscribed", "chan_self_unsub"},
|
14: {"main", "chan_self_subscribed", "chan_self_unsub"},
|
||||||
@ -232,18 +212,18 @@ func TestListChannelsSubscribedAny(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testdata := map[int][]string{
|
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"},
|
1: {"main", "private"},
|
||||||
2: {"main", "ü", "ö", "ä"},
|
2: {"main", "Ü", "Ö", "Ä"},
|
||||||
3: {"main", "\U0001f5ff", "innovations", "reminders"},
|
3: {"main", "\U0001f5ff", "Innovations", "Reminders"},
|
||||||
4: {"main"},
|
4: {"main"},
|
||||||
5: {"main", "test1", "test2", "test3", "test4", "test5"},
|
5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"},
|
||||||
6: {"main", "security", "lipsum"},
|
6: {"main", "Security", "Lipsum"},
|
||||||
7: {"main"},
|
7: {"main"},
|
||||||
8: {"main"},
|
8: {"main"},
|
||||||
9: {"main", "manual@chan"},
|
9: {"main", "manual@chan"},
|
||||||
10: {"main"},
|
10: {"main"},
|
||||||
11: {"promotions"},
|
11: {"Promotions"},
|
||||||
12: {},
|
12: {},
|
||||||
13: {},
|
13: {},
|
||||||
14: {"main", "chan_self_subscribed", "chan_other_request", "chan_other_accepted"},
|
14: {"main", "chan_self_subscribed", "chan_other_request", "chan_other_accepted"},
|
||||||
@ -267,18 +247,18 @@ func TestListChannelsAllAny(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testdata := map[int][]string{
|
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"},
|
1: {"main", "private"},
|
||||||
2: {"main", "ü", "ö", "ä"},
|
2: {"main", "Ü", "Ö", "Ä"},
|
||||||
3: {"main", "\U0001f5ff", "innovations", "reminders"},
|
3: {"main", "\U0001f5ff", "Innovations", "Reminders"},
|
||||||
4: {"main"},
|
4: {"main"},
|
||||||
5: {"main", "test1", "test2", "test3", "test4", "test5"},
|
5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"},
|
||||||
6: {"main", "security", "lipsum"},
|
6: {"main", "Security", "Lipsum"},
|
||||||
7: {"main"},
|
7: {"main"},
|
||||||
8: {"main"},
|
8: {"main"},
|
||||||
9: {"main", "manual@chan"},
|
9: {"main", "manual@chan"},
|
||||||
10: {"main"},
|
10: {"main"},
|
||||||
11: {"promotions"},
|
11: {"Promotions"},
|
||||||
12: {},
|
12: {},
|
||||||
13: {},
|
13: {},
|
||||||
14: {"main", "chan_self_subscribed", "chan_self_unsub", "chan_other_request", "chan_other_accepted"},
|
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{
|
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"},
|
1: {"main", "private"},
|
||||||
2: {"main", "ü", "ö", "ä"},
|
2: {"main", "Ü", "Ö", "Ä"},
|
||||||
3: {"main", "\U0001f5ff", "innovations", "reminders"},
|
3: {"main", "\U0001f5ff", "Innovations", "Reminders"},
|
||||||
4: {"main"},
|
4: {"main"},
|
||||||
5: {"main", "test1", "test2", "test3", "test4", "test5"},
|
5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"},
|
||||||
6: {"main", "security", "lipsum"},
|
6: {"main", "Security", "Lipsum"},
|
||||||
7: {"main"},
|
7: {"main"},
|
||||||
8: {"main"},
|
8: {"main"},
|
||||||
9: {"main", "manual@chan"},
|
9: {"main", "manual@chan"},
|
||||||
10: {"main"},
|
10: {"main"},
|
||||||
11: {"promotions"},
|
11: {"Promotions"},
|
||||||
12: {},
|
12: {},
|
||||||
13: {},
|
13: {},
|
||||||
14: {"main", "chan_self_subscribed", "chan_other_accepted"},
|
14: {"main", "chan_self_subscribed", "chan_other_accepted"},
|
||||||
@ -337,18 +317,18 @@ func TestListChannelsAll(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
testdata := map[int][]string{
|
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"},
|
1: {"main", "private"},
|
||||||
2: {"main", "ü", "ö", "ä"},
|
2: {"main", "Ü", "Ö", "Ä"},
|
||||||
3: {"main", "\U0001f5ff", "innovations", "reminders"},
|
3: {"main", "\U0001f5ff", "Innovations", "Reminders"},
|
||||||
4: {"main"},
|
4: {"main"},
|
||||||
5: {"main", "test1", "test2", "test3", "test4", "test5"},
|
5: {"main", "Test1", "Test2", "Test3", "Test4", "Test5"},
|
||||||
6: {"main", "security", "lipsum"},
|
6: {"main", "Security", "Lipsum"},
|
||||||
7: {"main"},
|
7: {"main"},
|
||||||
8: {"main"},
|
8: {"main"},
|
||||||
9: {"main", "manual@chan"},
|
9: {"main", "manual@chan"},
|
||||||
10: {"main"},
|
10: {"main"},
|
||||||
11: {"promotions"},
|
11: {"Promotions"},
|
||||||
12: {},
|
12: {},
|
||||||
13: {},
|
13: {},
|
||||||
14: {"main", "chan_self_subscribed", "chan_self_unsub", "chan_other_accepted"},
|
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
|
// [2] fail to update display_name
|
||||||
|
|
||||||
tt.RequestAuthPatchShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", uid, chanid), gin.H{
|
tt.RequestAuthPatchShouldFail(t, admintok, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s", uid, chanid), gin.H{
|
||||||
"display_name": "SERVER-ALERTS2",
|
"display_name": "",
|
||||||
}, 400, apierr.CHANNEL_NAME_WOULD_CHANGE)
|
}, 400, apierr.CHANNEL_NAME_EMPTY)
|
||||||
|
|
||||||
// [3] renew subscribe_key
|
// [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))
|
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
|
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
|
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
|
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))
|
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))
|
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" })
|
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" })
|
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" })
|
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{
|
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_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{
|
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_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{
|
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_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{
|
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)
|
0, 0, 0)
|
||||||
|
|
||||||
chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{
|
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{
|
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{
|
chan3 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UserID), gin.H{
|
||||||
"name": "chan3",
|
"name": "Chan3",
|
||||||
})
|
})
|
||||||
|
|
||||||
countBoth(
|
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{
|
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_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{
|
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,
|
"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{
|
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_owner_user_id": data2.UserID,
|
||||||
"channel_internal_name": "chan3",
|
"channel_internal_name": "Chan3",
|
||||||
})
|
})
|
||||||
|
|
||||||
countBoth(
|
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{
|
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)
|
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{
|
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{
|
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_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)
|
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{
|
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{
|
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{
|
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{
|
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{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
"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) {
|
if !langext.ArrEqualsExact(actual, expected) {
|
||||||
t.Errorf("Value [%s] differs (%T <-> %T):\n", key, expected, actual)
|
t.Errorf("Value [%s] differs (%T <-> %T):\n", key, expected, actual)
|
||||||
|
|
||||||
t.Errorf("Actual := [%v]\n", actual)
|
t.Errorf("Actual := [%v]\n", ljson(actual))
|
||||||
t.Errorf("Expected := [%v]\n", expected)
|
t.Errorf("Expected := [%v]\n", ljson(expected))
|
||||||
|
|
||||||
t.Error(string(debug.Stack()))
|
t.Error(string(debug.Stack()))
|
||||||
|
|
||||||
@ -364,3 +365,8 @@ func IsWholeFloat[T langext.FloatConstraint](v T) bool {
|
|||||||
_, frac := math.Modf(math.Abs(float64(v)))
|
_, frac := math.Modf(math.Abs(float64(v)))
|
||||||
return frac == 0.0
|
return frac == 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ljson(v any) string {
|
||||||
|
b, _ := json.Marshal(v)
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user