From d4a8a2e7208cb278a35aea13a679b57260114865 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Schw=C3=B6rer?= Date: Sun, 28 May 2023 17:38:19 +0200 Subject: [PATCH] Tests[SendWithAdminKey, SendWithSendKey, SendWithReadKey, SendWithPermissionSendKey] --- scnserver/.idea/server.iml | 5 +- scnserver/test/send_test.go | 414 ++++++++++++++++++++++++++++++++- scnserver/test/util/common.go | 18 ++ scnserver/test/util/factory.go | 4 + 4 files changed, 438 insertions(+), 3 deletions(-) diff --git a/scnserver/.idea/server.iml b/scnserver/.idea/server.iml index 6a8929b..9f75a96 100644 --- a/scnserver/.idea/server.iml +++ b/scnserver/.idea/server.iml @@ -12,7 +12,10 @@ - + + + + diff --git a/scnserver/test/send_test.go b/scnserver/test/send_test.go index 64e3bac..51f088c 100644 --- a/scnserver/test/send_test.go +++ b/scnserver/test/send_test.go @@ -1373,8 +1373,418 @@ func TestSendParallel(t *testing.T) { } } -func TestSendToForeignChannelWithSendKey(t *testing.T) { - t.SkipNow() //TODO +func TestSendWithAdminKey(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + + type chanobj struct { + ChannelId string `json:"channel_id"` + DescriptionName string `json:"description_name"` + DisplayName string `json:"display_name"` + InternalName string `json:"internal_name"` + MessagesSent int `json:"messages_sent"` + OwnerUserId string `json:"owner_user_id"` + SubscribeKey string `json:"subscribe_key"` + Subscription struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } `json:"subscription"` + TimestampCreated string `json:"timestamp_created"` + TimestampLastsent string `json:"timestamp_lastsent"` + } + type subobj struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } + type sublist struct { + Subscriptions []subobj `json:"subscriptions"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan1", + }) + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan2", + }) + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan3", + }) + + tt.AssertNotDefault(t, "chan1", chan1) + tt.AssertNotDefault(t, "chan2", chan2) + tt.AssertNotDefault(t, "chan3", chan3) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": data1.AdminKey, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": data1.AdminKey, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1001, 1), + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": data1.AdminKey, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1001, 1), + }) +} + +func TestSendWithSendKey(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + + type chanobj struct { + ChannelId string `json:"channel_id"` + DescriptionName string `json:"description_name"` + DisplayName string `json:"display_name"` + InternalName string `json:"internal_name"` + MessagesSent int `json:"messages_sent"` + OwnerUserId string `json:"owner_user_id"` + SubscribeKey string `json:"subscribe_key"` + Subscription struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } `json:"subscription"` + TimestampCreated string `json:"timestamp_created"` + TimestampLastsent string `json:"timestamp_lastsent"` + } + type subobj struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } + type sublist struct { + Subscriptions []subobj `json:"subscriptions"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan1", + }) + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan2", + }) + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan3", + }) + + tt.AssertNotDefault(t, "chan1", chan1) + tt.AssertNotDefault(t, "chan2", chan2) + tt.AssertNotDefault(t, "chan3", chan3) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": data1.SendKey, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": data1.SendKey, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1001, 1), + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": data1.SendKey, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1001, 1), + }) +} + +func TestSendWithReadKey(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + + type chanobj struct { + ChannelId string `json:"channel_id"` + DescriptionName string `json:"description_name"` + DisplayName string `json:"display_name"` + InternalName string `json:"internal_name"` + MessagesSent int `json:"messages_sent"` + OwnerUserId string `json:"owner_user_id"` + SubscribeKey string `json:"subscribe_key"` + Subscription struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } `json:"subscription"` + TimestampCreated string `json:"timestamp_created"` + TimestampLastsent string `json:"timestamp_lastsent"` + } + type subobj struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } + type sublist struct { + Subscriptions []subobj `json:"subscriptions"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan1", + }) + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan2", + }) + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan3", + }) + + tt.AssertNotDefault(t, "chan1", chan1) + tt.AssertNotDefault(t, "chan2", chan2) + tt.AssertNotDefault(t, "chan3", chan3) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": data1.ReadKey, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": data1.ReadKey, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1002, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": data1.ReadKey, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1003, 1), + }, 401, apierr.USER_AUTH_FAILED) +} + +func TestSendWithPermissionSendKey(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + + type chanobj struct { + ChannelId string `json:"channel_id"` + DescriptionName string `json:"description_name"` + DisplayName string `json:"display_name"` + InternalName string `json:"internal_name"` + MessagesSent int `json:"messages_sent"` + OwnerUserId string `json:"owner_user_id"` + SubscribeKey string `json:"subscribe_key"` + Subscription struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } `json:"subscription"` + TimestampCreated string `json:"timestamp_created"` + TimestampLastsent string `json:"timestamp_lastsent"` + } + type subobj struct { + ChannelId string `json:"channel_id"` + ChannelInternalName string `json:"channel_internal_name"` + ChannelOwnerUserId string `json:"channel_owner_user_id"` + Confirmed bool `json:"confirmed"` + SubscriberUserId string `json:"subscriber_user_id"` + SubscriptionId string `json:"subscription_id"` + TimestampCreated string `json:"timestamp_created"` + } + type sublist struct { + Subscriptions []subobj `json:"subscriptions"` + } + type keyobj struct { + AllChannels bool `json:"all_channels"` + Channels []string `json:"channels"` + KeytokenId string `json:"keytoken_id"` + MessagesSent int `json:"messages_sent"` + Name string `json:"name"` + OwnerUserId string `json:"owner_user_id"` + Permissions string `json:"permissions"` + Token string `json:"token"` // only in create + } + + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan1", + }) + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan2", + }) + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan3", + }) + chan4 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + "name": "Chan4", + }) + + tt.AssertNotDefault(t, "chan1", chan1) + tt.AssertNotDefault(t, "chan2", chan2) + tt.AssertNotDefault(t, "chan3", chan3) + tt.AssertNotDefault(t, "chan4", chan4) + + { + keyOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UserID), gin.H{ + "all_channels": false, + "channels": []string{chan1.ChannelId, chan2.ChannelId, chan3.ChannelId}, + "name": "K2", + "permissions": "CS", + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": keyOK.Token, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": keyOK.Token, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1002, 1), + }) + + tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ + "key": keyOK.Token, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1003, 1), + }) + } + + { + keyNOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UserID), gin.H{ + "all_channels": false, + "channels": []string{}, + "name": "K3", + "permissions": "CS", + }) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1002, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1003, 1), + }, 401, apierr.USER_AUTH_FAILED) + } + + { + keyNOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UserID), gin.H{ + "all_channels": false, + "channels": []string{chan4.ChannelId}, + "name": "K4", + "permissions": "CS", + }) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1002, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1003, 1), + }, 401, apierr.USER_AUTH_FAILED) + } + + { + keyNOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UserID), gin.H{ + "all_channels": false, + "channels": []string{chan1.ChannelId, chan2.ChannelId, chan3.ChannelId}, + "name": "K4", + "permissions": "CR", + }) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan1", + "title": tt.LipsumWord(1001, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan2", + "title": tt.LipsumWord(1002, 1), + }, 401, apierr.USER_AUTH_FAILED) + + tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ + "key": keyNOK.Token, + "user_id": data1.UserID, + "channel": "Chan3", + "title": tt.LipsumWord(1003, 1), + }, 401, apierr.USER_AUTH_FAILED) + } + } func TestSendDeliveryRetry(t *testing.T) { diff --git a/scnserver/test/util/common.go b/scnserver/test/util/common.go index e1b7f6c..0041b9f 100644 --- a/scnserver/test/util/common.go +++ b/scnserver/test/util/common.go @@ -177,6 +177,24 @@ func AssertTrue(t *testing.T, key string, v bool) { } } +func AssertNotDefault[T comparable](t *testing.T, key string, v T) { + if v == *new(T) { + t.Errorf("AssertNotDefault(%s) failed", key) + t.Error(ljson(v)) + t.Error(string(debug.Stack())) + t.FailNow() + } +} + +func AssertNotDefaultAny[T any](t *testing.T, key string, v T) { + if ljson(v) == ljson(*new(T)) { + t.Errorf("AssertNotDefault(%s) failed", key) + t.Error(ljson(v)) + t.Error(string(debug.Stack())) + t.FailNow() + } +} + func AssertNotEqual(t *testing.T, key string, expected any, actual any) { if expected == actual || (langext.IsNil(expected) && langext.IsNil(actual)) { t.Errorf("Value [%s] does not differ (%T <-> %T):\n", key, expected, actual) diff --git a/scnserver/test/util/factory.go b/scnserver/test/util/factory.go index 3226dc4..a3c531c 100644 --- a/scnserver/test/util/factory.go +++ b/scnserver/test/util/factory.go @@ -546,6 +546,10 @@ func doAcceptSub(t *testing.T, baseUrl string, user Userdat, subscriber Userdat, } +func LipsumWord(seed int64, wordcount int) string { + return loremipsum.NewWithSeed(seed).Words(wordcount) +} + func Lipsum(seed int64, paracount int) string { return loremipsum.NewWithSeed(seed).Paragraphs(paracount) }