diff --git a/scnserver/api/handler/apiSubscription.go b/scnserver/api/handler/apiSubscription.go index 7a86a99..10bab87 100644 --- a/scnserver/api/handler/apiSubscription.go +++ b/scnserver/api/handler/apiSubscription.go @@ -349,6 +349,22 @@ func (h APIHandler) CreateSubscription(g *gin.Context) ginresp.HTTPResponse { return ginresp.APIError(g, 401, apierr.USER_AUTH_FAILED, "You are not authorized for this action", nil) } + existingSub, err := h.database.GetSubscriptionBySubscriber(ctx, u.UserID, channel.ChannelID) + if err != nil { + return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to query existing subscription", err) + } + if existingSub != nil { + if !existingSub.Confirmed && channel.OwnerUserID == u.UserID { + err = h.database.UpdateSubscriptionConfirmed(ctx, existingSub.SubscriptionID, true) + if err != nil { + return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to update subscription", err) + } + existingSub.Confirmed = true + } + + return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, existingSub.JSON())) + } + sub, err := h.database.CreateSubscription(ctx, u.UserID, channel, channel.OwnerUserID == u.UserID) if err != nil { return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to create subscription", err) diff --git a/scnserver/test/channel_test.go b/scnserver/test/channel_test.go index 175f4c8..e8c3dd6 100644 --- a/scnserver/test/channel_test.go +++ b/scnserver/test/channel_test.go @@ -687,40 +687,40 @@ func TestListChannelSubscriptions(t *testing.T) { } countBoth := func(oa1, oc1, ou1, ia1, ic1, iu1, oa2, oc2, ou2, ia2, ic2, iu2 int) { - sublist1oa := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UserID, "outgoing_all")) + sublist1oa := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UID, "outgoing_all")) tt.AssertEqual(t, "1:outgoing_all", oa1, len(sublist1oa.Subscriptions)) - sublist1oc := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UserID, "outgoing_confirmed")) + sublist1oc := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UID, "outgoing_confirmed")) tt.AssertEqual(t, "1:outgoing_confirmed", oc1, len(sublist1oc.Subscriptions)) - sublist1ou := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UserID, "outgoing_unconfirmed")) + sublist1ou := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UID, "outgoing_unconfirmed")) tt.AssertEqual(t, "1:outgoing_unconfirmed", ou1, len(sublist1ou.Subscriptions)) - sublist1ia := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UserID, "incoming_all")) + sublist1ia := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UID, "incoming_all")) tt.AssertEqual(t, "1:incoming_all", ia1, len(sublist1ia.Subscriptions)) - sublist1ic := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UserID, "incoming_confirmed")) + sublist1ic := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UID, "incoming_confirmed")) tt.AssertEqual(t, "1:incoming_confirmed", ic1, len(sublist1ic.Subscriptions)) - sublist1iu := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UserID, "incoming_unconfirmed")) + sublist1iu := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data1.UID, "incoming_unconfirmed")) tt.AssertEqual(t, "1:incoming_unconfirmed", iu1, len(sublist1iu.Subscriptions)) - sublist2oa := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "outgoing_all")) + sublist2oa := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "outgoing_all")) tt.AssertEqual(t, "2:outgoing_all", oa2, len(sublist2oa.Subscriptions)) - sublist2oc := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "outgoing_confirmed")) + sublist2oc := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "outgoing_confirmed")) tt.AssertEqual(t, "2:outgoing_confirmed", oc2, len(sublist2oc.Subscriptions)) - sublist2ou := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "outgoing_unconfirmed")) + sublist2ou := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "outgoing_unconfirmed")) tt.AssertEqual(t, "2:outgoing_unconfirmed", ou2, len(sublist2ou.Subscriptions)) - sublist2ia := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "incoming_all")) + sublist2ia := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "incoming_all")) tt.AssertEqual(t, "2:incoming_all", ia2, len(sublist2ia.Subscriptions)) - sublist2ic := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "incoming_confirmed")) + sublist2ic := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "incoming_confirmed")) tt.AssertEqual(t, "2:incoming_confirmed", ic2, len(sublist2ic.Subscriptions)) - sublist2iu := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "incoming_unconfirmed")) + sublist2iu := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "incoming_unconfirmed")) tt.AssertEqual(t, "2:incoming_unconfirmed", iu2, len(sublist2iu.Subscriptions)) } @@ -730,13 +730,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.UID), gin.H{ "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.UID), gin.H{ "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.UID), gin.H{ "name": "Chan3", }) @@ -746,15 +746,15 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 3, 3, 0) - 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, + sub1 := tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_owner_user_id": data2.UID, "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.UID, 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, + sub3 := tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan3.SubscribeKey), gin.H{ + "channel_owner_user_id": data2.UID, "channel_internal_name": "Chan3", }) @@ -764,7 +764,7 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 6, 3, 3) - tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub1["subscription_id"]), gin.H{ + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1["subscription_id"]), gin.H{ "confirmed": true, }) @@ -774,7 +774,7 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 6, 4, 2) - tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub2["subscription_id"]), gin.H{ + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub2["subscription_id"]), gin.H{ "confirmed": true, }) @@ -784,7 +784,7 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 6, 5, 1) - tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub3["subscription_id"]), gin.H{ + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub3["subscription_id"]), gin.H{ "confirmed": true, }) @@ -794,7 +794,7 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 6, 6, 0) - tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub1["subscription_id"]), gin.H{}) + tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1["subscription_id"]), gin.H{}) countBoth( 2, 2, 0, @@ -802,7 +802,7 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 5, 5, 0) - tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub2["subscription_id"]), gin.H{}) + tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub2["subscription_id"]), gin.H{}) countBoth( 1, 1, 0, @@ -810,7 +810,7 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 4, 4, 0) - tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub3["subscription_id"]), gin.H{}) + tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub3["subscription_id"]), gin.H{}) countBoth( 0, 0, 0, @@ -818,9 +818,9 @@ func TestListChannelSubscriptions(t *testing.T) { 3, 3, 0, 3, 3, 0) - sublistRem := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UserID, "incoming_confirmed")) + sublistRem := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", data2.UID, "incoming_confirmed")) for _, v := range sublistRem.Subscriptions { - tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, v.SubscriptionId), gin.H{}) + tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, v.SubscriptionId), gin.H{}) } countBoth( @@ -883,11 +883,11 @@ func TestListChannelMessagesOfUnsubscribed(t *testing.T) { Channels []chanobj `json:"channels"` } - 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.UID), gin.H{ "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.UID, chan1.ChannelId), 401, apierr.USER_AUTH_FAILED) } func TestListChannelMessagesOfUnconfirmed1(t *testing.T) { @@ -943,16 +943,16 @@ func TestListChannelMessagesOfUnconfirmed1(t *testing.T) { Channels []chanobj `json:"channels"` } - 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.UID), gin.H{ "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, + tt.RequestAuthPost[gin.H](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_owner_user_id": data2.UID, "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.UID, chan1.ChannelId), 401, apierr.USER_AUTH_FAILED) } func TestListChannelMessagesOfUnconfirmed2(t *testing.T) { @@ -1008,15 +1008,15 @@ func TestListChannelMessagesOfUnconfirmed2(t *testing.T) { Channels []chanobj `json:"channels"` } - 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.UID), gin.H{ "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.UID, chan1.SubscribeKey), gin.H{ "channel_id": chan1.ChannelId, }) - 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.UID, chan1.ChannelId), 401, apierr.USER_AUTH_FAILED) } func TestListChannelMessagesOfRevokedConfirmation(t *testing.T) { @@ -1072,21 +1072,21 @@ func TestListChannelMessagesOfRevokedConfirmation(t *testing.T) { Channels []chanobj `json:"channels"` } - 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.UID), gin.H{ "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.UID, chan1.SubscribeKey), gin.H{ "channel_id": chan1.ChannelId, }) - tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub1["subscription_id"]), gin.H{ + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1["subscription_id"]), gin.H{ "confirmed": true, }) - tt.RequestAuthGet[tt.Void](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/messages", data1.UserID, chan1.ChannelId)) + tt.RequestAuthGet[tt.Void](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/messages", data1.UID, chan1.ChannelId)) - tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UserID, sub1["subscription_id"]), gin.H{}) + tt.RequestAuthDelete[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1["subscription_id"]), gin.H{}) - 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.UID, chan1.ChannelId), 401, apierr.USER_AUTH_FAILED) } diff --git a/scnserver/test/keytoken_test.go b/scnserver/test/keytoken_test.go index 759b5c7..4a2a972 100644 --- a/scnserver/test/keytoken_test.go +++ b/scnserver/test/keytoken_test.go @@ -29,7 +29,7 @@ func TestTokenKeys(t *testing.T) { } { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 3, len(klist.Keys)) tt.AssertArrAny(t, "keys->any[Admin]", klist.Keys, func(s keyobj) bool { @@ -43,7 +43,7 @@ func TestTokenKeys(t *testing.T) { }) } - key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": true, "channels": []string{}, "name": "Admin2", @@ -55,33 +55,33 @@ func TestTokenKeys(t *testing.T) { tt.AssertEqual(t, "AllChannels", true, key2.AllChannels) { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 4, len(klist.Keys)) } - key3 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key2.KeytokenId)) + key3 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key2.KeytokenId)) tt.AssertEqual(t, "KeytokenId", key2.KeytokenId, key3.KeytokenId) - tt.AssertEqual(t, "UserID", data.UserID, key3.OwnerUserId) + tt.AssertEqual(t, "UserID", data.UID, key3.OwnerUserId) tt.AssertEqual(t, "Name", "Admin2", key3.Name) tt.AssertEqual(t, "Permissions", "A", key3.Permissions) tt.AssertEqual(t, "AllChannels", true, key3.AllChannels) - tt.RequestAuthDelete[tt.Void](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key2.KeytokenId), gin.H{}) + tt.RequestAuthDelete[tt.Void](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key2.KeytokenId), gin.H{}) - tt.RequestAuthGetShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key2.KeytokenId), 404, apierr.KEY_NOT_FOUND) + tt.RequestAuthGetShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key2.KeytokenId), 404, apierr.KEY_NOT_FOUND) { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 3, len(klist.Keys)) } - chan0 := tt.RequestAuthPost[gin.H](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.UserID), gin.H{ + chan0 := tt.RequestAuthPost[gin.H](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.UID), gin.H{ "name": "testchan1", }) chanid := fmt.Sprintf("%v", chan0["channel_id"]) - key4 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key4 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": false, "channels": []string{chanid}, "name": "TKey1", @@ -92,7 +92,7 @@ func TestTokenKeys(t *testing.T) { tt.AssertEqual(t, "AllChannels", false, key4.AllChannels) tt.AssertStrRepEqual(t, "Channels", []string{chanid}, key4.Channels) - key5 := tt.RequestAuthPatch[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key4.KeytokenId), gin.H{ + key5 := tt.RequestAuthPatch[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key4.KeytokenId), gin.H{ "all_channels": true, "channels": []string{}, "name": "TKey2-A", @@ -103,13 +103,13 @@ func TestTokenKeys(t *testing.T) { tt.AssertEqual(t, "AllChannels", true, key5.AllChannels) tt.AssertStrRepEqual(t, "Channels", []string{}, key5.Channels) - key6 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key5.KeytokenId)) + key6 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key5.KeytokenId)) tt.AssertEqual(t, "Name", "TKey2-A", key6.Name) tt.AssertEqual(t, "Permissions", "A", key6.Permissions) tt.AssertEqual(t, "AllChannels", true, key6.AllChannels) tt.AssertStrRepEqual(t, "Channels", []string{}, key6.Channels) - key7 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key7 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": false, "channels": []string{chanid}, "name": "TKey7", @@ -117,13 +117,13 @@ func TestTokenKeys(t *testing.T) { }) { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 5, len(klist.Keys)) } msg1s := tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": key7.Token, - "user_id": data.UserID, + "user_id": data.UID, "channel": "testchan1", "title": "HelloWorld_001", }) @@ -134,22 +134,22 @@ func TestTokenKeys(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": key7.Token, - "user_id": data.UserID, + "user_id": data.UID, "channel": "testchan2", "title": "HelloWorld_001", }, 401, apierr.USER_AUTH_FAILED) // wrong channel tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": key7.Token, - "user_id": data.UserID, + "user_id": data.UID, "title": "HelloWorld_001", }, 401, apierr.USER_AUTH_FAILED) // no channel (=main) - tt.RequestAuthGetShouldFail(t, key7.Token, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.UserID), 401, apierr.USER_AUTH_FAILED) // no user read perm + tt.RequestAuthGetShouldFail(t, key7.Token, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.UID), 401, apierr.USER_AUTH_FAILED) // no user read perm - tt.RequestAuthPatchShouldFail(t, key7.Token, baseUrl, "/api/v2/users/"+data.UserID, gin.H{"username": "my_user_001"}, 401, apierr.USER_AUTH_FAILED) // no user update perm + tt.RequestAuthPatchShouldFail(t, key7.Token, baseUrl, "/api/v2/users/"+data.UID, gin.H{"username": "my_user_001"}, 401, apierr.USER_AUTH_FAILED) // no user update perm - key8 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key8 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": true, "channels": []string{}, "name": "TKey7", @@ -158,7 +158,7 @@ func TestTokenKeys(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": key8.Token, - "user_id": data.UserID, + "user_id": data.UID, "title": "HelloWorld_001", }, 401, apierr.USER_AUTH_FAILED) // no send perm @@ -184,7 +184,7 @@ func TestTokenKeysInitial(t *testing.T) { Keys []keyobj `json:"keys"` } - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 3, len(klist.Keys)) tt.AssertArrAny(t, "keys->any[Admin]", klist.Keys, func(s keyobj) bool { @@ -218,7 +218,7 @@ func TestTokenKeysCreate(t *testing.T) { Keys []keyobj `json:"keys"` } - key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": true, "channels": []string{}, "name": "Admin2", @@ -230,14 +230,14 @@ func TestTokenKeysCreate(t *testing.T) { tt.AssertEqual(t, "AllChannels", true, key2.AllChannels) { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 4, len(klist.Keys)) } - key3 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key2.KeytokenId)) + key3 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key2.KeytokenId)) tt.AssertEqual(t, "KeytokenId", key2.KeytokenId, key3.KeytokenId) - tt.AssertEqual(t, "UserID", data.UserID, key3.OwnerUserId) + tt.AssertEqual(t, "UserID", data.UID, key3.OwnerUserId) tt.AssertEqual(t, "Name", "Admin2", key3.Name) tt.AssertEqual(t, "Permissions", "A", key3.Permissions) tt.AssertEqual(t, "AllChannels", true, key3.AllChannels) @@ -264,7 +264,7 @@ func TestTokenKeysUpdate(t *testing.T) { Keys []keyobj `json:"keys"` } - key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": true, "channels": []string{}, "name": "Admin2", @@ -275,15 +275,15 @@ func TestTokenKeysUpdate(t *testing.T) { tt.AssertEqual(t, "Permissions", "A", key2.Permissions) tt.AssertEqual(t, "AllChannels", true, key2.AllChannels) - key3 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key2.KeytokenId)) + key3 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key2.KeytokenId)) tt.AssertEqual(t, "KeytokenId", key2.KeytokenId, key3.KeytokenId) - tt.AssertEqual(t, "UserID", data.UserID, key3.OwnerUserId) + tt.AssertEqual(t, "UserID", data.UID, key3.OwnerUserId) tt.AssertEqual(t, "Name", "Admin2", key3.Name) tt.AssertEqual(t, "Permissions", "A", key3.Permissions) tt.AssertEqual(t, "AllChannels", true, key3.AllChannels) - key5 := tt.RequestAuthPatch[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key3.KeytokenId), gin.H{ + key5 := tt.RequestAuthPatch[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key3.KeytokenId), gin.H{ "name": "Hello", }) tt.AssertEqual(t, "Name", "Hello", key5.Name) @@ -291,7 +291,7 @@ func TestTokenKeysUpdate(t *testing.T) { tt.AssertEqual(t, "AllChannels", true, key5.AllChannels) tt.AssertStrRepEqual(t, "Channels", []string{}, key5.Channels) - key6 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key5.KeytokenId)) + key6 := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key5.KeytokenId)) tt.AssertEqual(t, "Name", "Hello", key6.Name) tt.AssertEqual(t, "Permissions", "A", key6.Permissions) tt.AssertEqual(t, "AllChannels", true, key6.AllChannels) @@ -319,7 +319,7 @@ func TestTokenKeysDelete(t *testing.T) { Keys []keyobj `json:"keys"` } - key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key2 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": true, "channels": []string{}, "name": "Admin2", @@ -331,14 +331,14 @@ func TestTokenKeysDelete(t *testing.T) { tt.AssertEqual(t, "AllChannels", true, key2.AllChannels) { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 4, len(klist.Keys)) } - tt.RequestAuthDelete[tt.Void](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, key2.KeytokenId), gin.H{}) + tt.RequestAuthDelete[tt.Void](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, key2.KeytokenId), gin.H{}) { - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) tt.AssertEqual(t, "len(keys)", 3, len(klist.Keys)) } @@ -364,7 +364,7 @@ func TestTokenKeysDeleteSelf(t *testing.T) { Keys []keyobj `json:"keys"` } - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) ak := "" for _, v := range klist.Keys { @@ -373,7 +373,7 @@ func TestTokenKeysDeleteSelf(t *testing.T) { } } - tt.RequestAuthDeleteShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, ak), gin.H{}, 400, apierr.CANNOT_SELFDELETE_KEY) + tt.RequestAuthDeleteShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, ak), gin.H{}, 400, apierr.CANNOT_SELFDELETE_KEY) } func TestTokenKeysDowngradeSelf(t *testing.T) { @@ -396,7 +396,7 @@ func TestTokenKeysDowngradeSelf(t *testing.T) { Keys []keyobj `json:"keys"` } - klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID)) + klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID)) ak := "" for _, v := range klist.Keys { @@ -405,25 +405,25 @@ func TestTokenKeysDowngradeSelf(t *testing.T) { } } - tt.RequestAuthPatchShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, ak), gin.H{ + tt.RequestAuthPatchShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, ak), gin.H{ "permissions": "CR", }, 400, apierr.CANNOT_SELFUPDATE_KEY) - tt.RequestAuthPatchShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, ak), gin.H{ + tt.RequestAuthPatchShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, ak), gin.H{ "all_channels": false, }, 400, apierr.CANNOT_SELFUPDATE_KEY) - tt.RequestAuthPatchShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, ak), gin.H{ + tt.RequestAuthPatchShouldFail(t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, ak), gin.H{ "channels": []string{"main"}, }, 400, apierr.CANNOT_SELFUPDATE_KEY) - tt.RequestAuthPatch[tt.Void](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, ak), gin.H{ + tt.RequestAuthPatch[tt.Void](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, ak), gin.H{ "name": "This-is-allowed", }) - keyOut := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UserID, ak)) + keyOut := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/%s", data.UID, ak)) - tt.AssertEqual(t, "UserID", data.UserID, keyOut.OwnerUserId) + tt.AssertEqual(t, "UserID", data.UID, keyOut.OwnerUserId) tt.AssertEqual(t, "Name", "This-is-allowed", keyOut.Name) tt.AssertEqual(t, "Permissions", "A", keyOut.Permissions) tt.AssertEqual(t, "AllChannels", true, keyOut.AllChannels) @@ -448,12 +448,12 @@ func TestTokenKeysPermissions(t *testing.T) { Token string `json:"token"` // only in create } - chan0 := tt.RequestAuthPost[gin.H](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.UserID), gin.H{ + chan0 := tt.RequestAuthPost[gin.H](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data.UID), gin.H{ "name": "testchan1", }) chanid := fmt.Sprintf("%v", chan0["channel_id"]) - key7 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key7 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": false, "channels": []string{chanid}, "name": "TKey7", @@ -462,22 +462,22 @@ func TestTokenKeysPermissions(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": key7.Token, - "user_id": data.UserID, + "user_id": data.UID, "channel": "testchan2", "title": "HelloWorld_001", }, 401, apierr.USER_AUTH_FAILED) // wrong channel tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": key7.Token, - "user_id": data.UserID, + "user_id": data.UID, "title": "HelloWorld_001", }, 401, apierr.USER_AUTH_FAILED) // no channel (=main) - tt.RequestAuthGetShouldFail(t, key7.Token, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.UserID), 401, apierr.USER_AUTH_FAILED) // no user read perm + tt.RequestAuthGetShouldFail(t, key7.Token, baseUrl, fmt.Sprintf("/api/v2/users/%s", data.UID), 401, apierr.USER_AUTH_FAILED) // no user read perm - tt.RequestAuthPatchShouldFail(t, key7.Token, baseUrl, "/api/v2/users/"+data.UserID, gin.H{"username": "my_user_001"}, 401, apierr.USER_AUTH_FAILED) // no user update perm + tt.RequestAuthPatchShouldFail(t, key7.Token, baseUrl, "/api/v2/users/"+data.UID, gin.H{"username": "my_user_001"}, 401, apierr.USER_AUTH_FAILED) // no user update perm - key8 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UserID), gin.H{ + key8 := tt.RequestAuthPost[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID), gin.H{ "all_channels": true, "channels": []string{}, "name": "TKey7", @@ -486,7 +486,7 @@ func TestTokenKeysPermissions(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": key8.Token, - "user_id": data.UserID, + "user_id": data.UID, "title": "HelloWorld_001", }, 401, apierr.USER_AUTH_FAILED) // no send perm diff --git a/scnserver/test/send_test.go b/scnserver/test/send_test.go index 51f088c..682f0fb 100644 --- a/scnserver/test/send_test.go +++ b/scnserver/test/send_test.go @@ -1412,13 +1412,13 @@ func TestSendWithAdminKey(t *testing.T) { Subscriptions []subobj `json:"subscriptions"` } - chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan1", }) - chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan2", }) - chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan3", }) @@ -1428,21 +1428,21 @@ func TestSendWithAdminKey(t *testing.T) { tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": data1.AdminKey, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan1", "title": tt.LipsumWord(1001, 1), }) tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": data1.AdminKey, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan2", "title": tt.LipsumWord(1001, 1), }) tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": data1.AdminKey, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan3", "title": tt.LipsumWord(1001, 1), }) @@ -1487,13 +1487,13 @@ func TestSendWithSendKey(t *testing.T) { Subscriptions []subobj `json:"subscriptions"` } - chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan1", }) - chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan2", }) - chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan3", }) @@ -1503,21 +1503,21 @@ func TestSendWithSendKey(t *testing.T) { tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": data1.SendKey, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan1", "title": tt.LipsumWord(1001, 1), }) tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": data1.SendKey, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan2", "title": tt.LipsumWord(1001, 1), }) tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": data1.SendKey, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan3", "title": tt.LipsumWord(1001, 1), }) @@ -1562,13 +1562,13 @@ func TestSendWithReadKey(t *testing.T) { Subscriptions []subobj `json:"subscriptions"` } - chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan1", }) - chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan2", }) - chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan3", }) @@ -1578,21 +1578,21 @@ func TestSendWithReadKey(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": data1.ReadKey, - "user_id": data1.UserID, + "user_id": data1.UID, "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, + "user_id": data1.UID, "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, + "user_id": data1.UID, "channel": "Chan3", "title": tt.LipsumWord(1003, 1), }, 401, apierr.USER_AUTH_FAILED) @@ -1647,16 +1647,16 @@ func TestSendWithPermissionSendKey(t *testing.T) { 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{ + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan1", }) - chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan2 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan2", }) - chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan3 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan3", }) - chan4 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UserID), gin.H{ + chan4 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ "name": "Chan4", }) @@ -1666,7 +1666,7 @@ func TestSendWithPermissionSendKey(t *testing.T) { tt.AssertNotDefault(t, "chan4", chan4) { - keyOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UserID), gin.H{ + keyOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UID), gin.H{ "all_channels": false, "channels": []string{chan1.ChannelId, chan2.ChannelId, chan3.ChannelId}, "name": "K2", @@ -1675,28 +1675,28 @@ func TestSendWithPermissionSendKey(t *testing.T) { tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": keyOK.Token, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan1", "title": tt.LipsumWord(1001, 1), }) tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": keyOK.Token, - "user_id": data1.UserID, + "user_id": data1.UID, "channel": "Chan2", "title": tt.LipsumWord(1002, 1), }) tt.RequestPost[gin.H](t, baseUrl, "/", gin.H{ "key": keyOK.Token, - "user_id": data1.UserID, + "user_id": data1.UID, "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{ + keyNOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UID), gin.H{ "all_channels": false, "channels": []string{}, "name": "K3", @@ -1705,28 +1705,28 @@ func TestSendWithPermissionSendKey(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": keyNOK.Token, - "user_id": data1.UserID, + "user_id": data1.UID, "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, + "user_id": data1.UID, "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, + "user_id": data1.UID, "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{ + keyNOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UID), gin.H{ "all_channels": false, "channels": []string{chan4.ChannelId}, "name": "K4", @@ -1735,28 +1735,28 @@ func TestSendWithPermissionSendKey(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": keyNOK.Token, - "user_id": data1.UserID, + "user_id": data1.UID, "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, + "user_id": data1.UID, "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, + "user_id": data1.UID, "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{ + keyNOK := tt.RequestAuthPost[keyobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data1.UID), gin.H{ "all_channels": false, "channels": []string{chan1.ChannelId, chan2.ChannelId, chan3.ChannelId}, "name": "K4", @@ -1765,21 +1765,21 @@ func TestSendWithPermissionSendKey(t *testing.T) { tt.RequestPostShouldFail(t, baseUrl, "/", gin.H{ "key": keyNOK.Token, - "user_id": data1.UserID, + "user_id": data1.UID, "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, + "user_id": data1.UID, "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, + "user_id": data1.UID, "channel": "Chan3", "title": tt.LipsumWord(1003, 1), }, 401, apierr.USER_AUTH_FAILED) diff --git a/scnserver/test/subscription_test.go b/scnserver/test/subscription_test.go index d421074..8ad40d7 100644 --- a/scnserver/test/subscription_test.go +++ b/scnserver/test/subscription_test.go @@ -1,47 +1,1153 @@ package test -import "testing" +import ( + "blackforestbytes.com/simplecloudnotifier/api/apierr" + tt "blackforestbytes.com/simplecloudnotifier/test/util" + "fmt" + "github.com/gin-gonic/gin" + "gogs.mikescher.com/BlackForestBytes/goext/langext" + "testing" +) func TestListSubscriptionsOfUser(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data := tt.InitDefaultData(t, ws) + + 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 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 chanlist struct { + Channels []chanobj `json:"channels"` + } + + assertCount := func(u tt.Userdat, c int, sel string) { + slist := tt.RequestAuthGet[sublist](t, u.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", u.UID, sel)) + tt.AssertEqual(t, sel+".len", c, len(slist.Subscriptions)) + } + + assertCount(data.User[16], 3, "outgoing_all") + assertCount(data.User[16], 3, "outgoing_confirmed") + assertCount(data.User[16], 0, "outgoing_unconfirmed") + assertCount(data.User[16], 3, "incoming_all") + assertCount(data.User[16], 3, "incoming_confirmed") + assertCount(data.User[16], 0, "incoming_unconfirmed") + + 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" }) + + sub1 := tt.RequestAuthPost[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + sub2 := tt.RequestAuthPost[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan2.SubscribeKey), gin.H{ + "channel_id": chan2.ChannelId, + }) + sub3 := tt.RequestAuthPost[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan3.SubscribeKey), gin.H{ + "channel_id": chan3.ChannelId, + }) + + tt.AssertNotDefaultAny(t, "sub1", sub1) + tt.AssertNotDefaultAny(t, "sub2", sub2) + tt.AssertNotDefaultAny(t, "sub3", sub3) + + 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{ + "confirmed": true, + }) + + tt.RequestAuthDelete[gin.H](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, sub3["subscription_id"]), gin.H{}) + + assertCount(data.User[16], 3, "outgoing_all") + assertCount(data.User[16], 3, "outgoing_confirmed") + assertCount(data.User[16], 0, "outgoing_unconfirmed") + assertCount(data.User[16], 5, "incoming_all") + assertCount(data.User[16], 4, "incoming_confirmed") + assertCount(data.User[16], 1, "incoming_unconfirmed") + + 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{ + "confirmed": false, + }) + + assertCount(data.User[16], 5, "incoming_all") + assertCount(data.User[16], 3, "incoming_confirmed") + assertCount(data.User[16], 2, "incoming_unconfirmed") + + assertCount(data.User[0], 7, "outgoing_all") + assertCount(data.User[0], 5, "outgoing_confirmed") + assertCount(data.User[0], 2, "outgoing_unconfirmed") + assertCount(data.User[0], 5, "incoming_all") + assertCount(data.User[0], 5, "incoming_confirmed") + assertCount(data.User[0], 0, "incoming_unconfirmed") } func TestListSubscriptionsOfChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data := tt.InitDefaultData(t, ws) + + 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 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 chanlist struct { + Channels []chanobj `json:"channels"` + } + + assertCount := func(u tt.Userdat, cid *chanobj, c int) { + slist := tt.RequestAuthGet[sublist](t, u.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", u.UID, cid.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", c, len(slist.Subscriptions)) + } + + 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" }) + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) + + sub1 := tt.RequestAuthPost[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + assertCount(data.User[16], chan1, 2) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) + + sub2 := tt.RequestAuthPost[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan2.SubscribeKey), gin.H{ + "channel_id": chan2.ChannelId, + }) + + assertCount(data.User[16], chan1, 2) + assertCount(data.User[16], chan2, 2) + assertCount(data.User[16], chan3, 1) + + sub3 := tt.RequestAuthPost[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan3.SubscribeKey), gin.H{ + "channel_id": chan3.ChannelId, + }) + + assertCount(data.User[16], chan1, 2) + assertCount(data.User[16], chan2, 2) + assertCount(data.User[16], chan3, 2) + + 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{ + "confirmed": true, + }) + + assertCount(data.User[16], chan1, 2) + assertCount(data.User[16], chan2, 2) + assertCount(data.User[16], chan3, 2) + + tt.RequestAuthDelete[gin.H](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, sub3["subscription_id"]), gin.H{}) + + assertCount(data.User[16], chan1, 2) + assertCount(data.User[16], chan2, 2) + assertCount(data.User[16], chan3, 1) + + tt.RequestAuthDelete[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{}) + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 2) + assertCount(data.User[16], chan3, 1) + + tt.RequestAuthDelete[gin.H](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[0].UID, sub2["subscription_id"]), gin.H{}) + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) } func TestCreateSubscriptionToOwnChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data := tt.InitDefaultData(t, ws) + + 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 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 chanlist struct { + Channels []chanobj `json:"channels"` + } + + assertCount := func(u tt.Userdat, cid *chanobj, c int) { + slist := tt.RequestAuthGet[sublist](t, u.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", u.UID, cid.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", c, len(slist.Subscriptions)) + } + + 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" }) + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) + + { + slist := tt.RequestAuthGet[sublist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data.User[16].UID, chan1.ChannelId)) + tt.RequestAuthDelete[tt.Void](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, slist.Subscriptions[0].SubscriptionId), gin.H{}) + } + + { + slist := tt.RequestAuthGet[sublist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data.User[16].UID, chan3.ChannelId)) + tt.RequestAuthDelete[tt.Void](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, slist.Subscriptions[0].SubscriptionId), gin.H{}) + } + + assertCount(data.User[16], chan1, 0) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 0) + + { + sub0 := tt.RequestAuthPost[subobj](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[16].UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + tt.AssertEqual(t, "Confirmed", true, sub0.Confirmed) // sub to own channel == auto confirm + } + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 0) +} + +func TestCreateDoubleSubscriptionToOwnChannel(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data := tt.InitDefaultData(t, ws) + + 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 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 chanlist struct { + Channels []chanobj `json:"channels"` + } + + assertCount := func(u tt.Userdat, cid *chanobj, c int) { + slist := tt.RequestAuthGet[sublist](t, u.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", u.UID, cid.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", c, len(slist.Subscriptions)) + } + + 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" }) + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) + + { + slist := tt.RequestAuthGet[sublist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data.User[16].UID, chan1.ChannelId)) + tt.RequestAuthDelete[tt.Void](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, slist.Subscriptions[0].SubscriptionId), gin.H{}) + } + + { + slist := tt.RequestAuthGet[sublist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data.User[16].UID, chan3.ChannelId)) + tt.RequestAuthDelete[tt.Void](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, slist.Subscriptions[0].SubscriptionId), gin.H{}) + } + + assertCount(data.User[16], chan1, 0) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 0) + + sub0 := tt.RequestAuthPost[subobj](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions", data.User[16].UID), gin.H{ + "channel_id": chan1.ChannelId, + }) + tt.AssertEqual(t, "Confirmed", true, sub0.Confirmed) // sub to own channel == auto confirm + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 0) + + sub1 := tt.RequestAuthPost[subobj](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[16].UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + tt.AssertEqual(t, "Confirmed", true, sub1.Confirmed) // sub to own channel == auto confirm + tt.AssertEqual(t, "Confirmed", sub0.SubscriptionId, sub1.SubscriptionId) // same sub + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 0) } func TestCreateSubscriptionToForeignChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + gsub1 := tt.RequestAuthGet[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId)) + + gsub2 := tt.RequestAuthGet[subobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId)) + + tt.AssertEqual(t, "SubscriptionId", gsub1.SubscriptionId, gsub2.SubscriptionId) + } func TestGetSubscriptionToOwnChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data1.UID), gin.H{ + "name": "Chan1", + }) + + slist := tt.RequestAuthGet[sublist](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data1.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + + gsub1 := tt.RequestAuthGet[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, slist.Subscriptions[0].SubscriptionId)) + + tt.AssertEqual(t, "Confirmed", true, gsub1.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, gsub1.ChannelId) } func TestGetSubscriptionToForeignChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data := tt.InitDefaultData(t, ws) + + 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 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 chanlist struct { + Channels []chanobj `json:"channels"` + } + + assertCount := func(u tt.Userdat, c int, sel string) { + slist := tt.RequestAuthGet[sublist](t, u.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?selector=%s", u.UID, sel)) + tt.AssertEqual(t, sel+".len", c, len(slist.Subscriptions)) + } + + 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" }) + + sub1 := tt.RequestAuthPost[subobj](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + sub2 := tt.RequestAuthPost[subobj](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan2.SubscribeKey), gin.H{ + "channel_id": chan2.ChannelId, + }) + sub3 := tt.RequestAuthPost[subobj](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data.User[0].UID, chan3.SubscribeKey), gin.H{ + "channel_id": chan3.ChannelId, + }) + + tt.AssertNotDefaultAny(t, "sub1", sub1) + tt.AssertNotDefaultAny(t, "sub2", sub2) + tt.AssertNotDefaultAny(t, "sub3", sub3) + + tt.RequestAuthPatch[gin.H](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }) + + tt.RequestAuthDelete[gin.H](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, sub3.SubscriptionId), gin.H{}) + + assertCount(data.User[16], 3, "outgoing_all") + assertCount(data.User[16], 3, "outgoing_confirmed") + assertCount(data.User[16], 0, "outgoing_unconfirmed") + assertCount(data.User[16], 5, "incoming_all") + assertCount(data.User[16], 4, "incoming_confirmed") + assertCount(data.User[16], 1, "incoming_unconfirmed") + + assertCount(data.User[0], 7, "outgoing_all") + assertCount(data.User[0], 6, "outgoing_confirmed") + assertCount(data.User[0], 1, "outgoing_unconfirmed") + assertCount(data.User[0], 5, "incoming_all") + assertCount(data.User[0], 5, "incoming_confirmed") + assertCount(data.User[0], 0, "incoming_unconfirmed") + + gsub1 := tt.RequestAuthGet[subobj](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[0].UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "SubscriptionId", sub1.SubscriptionId, gsub1.SubscriptionId) + tt.AssertEqual(t, "Confirmed", true, gsub1.Confirmed) + + gsub2 := tt.RequestAuthGet[subobj](t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[0].UID, sub2.SubscriptionId)) + tt.AssertEqual(t, "SubscriptionId", sub2.SubscriptionId, gsub2.SubscriptionId) + tt.AssertEqual(t, "Confirmed", false, gsub2.Confirmed) + + tt.RequestAuthGetShouldFail(t, data.User[0].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[0].UID, sub3.SubscriptionId), 404, apierr.SUBSCRIPTION_NOT_FOUND) } func TestCancelSubscriptionToForeignChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + gsub1 := tt.RequestAuthGet[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId)) + + tt.RequestAuthDelete[tt.Void](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, gsub1.SubscriptionId), gin.H{}) + + tt.RequestAuthGetShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, gsub1.SubscriptionId), 404, apierr.SUBSCRIPTION_NOT_FOUND) } func TestCancelSubscriptionToOwnChannel(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data := tt.InitDefaultData(t, ws) + + 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 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 chanlist struct { + Channels []chanobj `json:"channels"` + } + + assertCount := func(u tt.Userdat, cid *chanobj, c int) { + slist := tt.RequestAuthGet[sublist](t, u.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", u.UID, cid.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", c, len(slist.Subscriptions)) + } + + 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" }) + + assertCount(data.User[16], chan1, 1) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) + + { + slist := tt.RequestAuthGet[sublist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data.User[16].UID, chan1.ChannelId)) + tt.RequestAuthDelete[tt.Void](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, slist.Subscriptions[0].SubscriptionId), gin.H{}) + } + + assertCount(data.User[16], chan1, 0) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 1) + + { + slist := tt.RequestAuthGet[sublist](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data.User[16].UID, chan3.ChannelId)) + tt.RequestAuthDelete[tt.Void](t, data.User[16].AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data.User[16].UID, slist.Subscriptions[0].SubscriptionId), gin.H{}) + } + + assertCount(data.User[16], chan1, 0) + assertCount(data.User[16], chan2, 1) + assertCount(data.User[16], chan3, 0) } func TestDenySubscription(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + } + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthDelete[tt.Void](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), gin.H{}) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + tt.RequestAuthGetShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), 404, apierr.SUBSCRIPTION_NOT_FOUND) + } } func TestConfirmSubscription(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + } + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthPatchShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }, 401, apierr.USER_AUTH_FAILED) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + for _, v := range slist.Subscriptions { + tt.AssertEqual(t, "Confirmed", true, v.Confirmed) + } + { + subAfter1 := tt.RequestAuthGet[subobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "Confirmed", true, subAfter1.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, subAfter1.ChannelId) + tt.AssertEqual(t, "SubscriberUserId", data1.UID, subAfter1.SubscriberUserId) + tt.AssertEqual(t, "ChannelOwnerUserId", data2.UID, subAfter1.ChannelOwnerUserId) + } + { + subAfter2 := tt.RequestAuthGet[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "Confirmed", true, subAfter2.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, subAfter2.ChannelId) + tt.AssertEqual(t, "SubscriberUserId", data1.UID, subAfter2.SubscriberUserId) + tt.AssertEqual(t, "ChannelOwnerUserId", data2.UID, subAfter2.ChannelOwnerUserId) + } + } } func TestUnconfirmSubscription(t *testing.T) { - t.SkipNow() //TODO + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + } + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthPatchShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }, 401, apierr.USER_AUTH_FAILED) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + for _, v := range slist.Subscriptions { + tt.AssertEqual(t, "Confirmed", true, v.Confirmed) + } + { + subAfter1 := tt.RequestAuthGet[subobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "Confirmed", true, subAfter1.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, subAfter1.ChannelId) + tt.AssertEqual(t, "SubscriberUserId", data1.UID, subAfter1.SubscriberUserId) + tt.AssertEqual(t, "ChannelOwnerUserId", data2.UID, subAfter1.ChannelOwnerUserId) + } + { + subAfter2 := tt.RequestAuthGet[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "Confirmed", true, subAfter2.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, subAfter2.ChannelId) + tt.AssertEqual(t, "SubscriberUserId", data1.UID, subAfter2.SubscriberUserId) + tt.AssertEqual(t, "ChannelOwnerUserId", data2.UID, subAfter2.ChannelOwnerUserId) + } + } + + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId), gin.H{ + "confirmed": false, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + for _, v := range slist.Subscriptions { + tt.AssertEqual(t, "Confirmed", v.SubscriberUserId == data2.UID, v.Confirmed) + } + { + subAfter1 := tt.RequestAuthGet[subobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "Confirmed", false, subAfter1.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, subAfter1.ChannelId) + tt.AssertEqual(t, "SubscriberUserId", data1.UID, subAfter1.SubscriberUserId) + tt.AssertEqual(t, "ChannelOwnerUserId", data2.UID, subAfter1.ChannelOwnerUserId) + } + { + subAfter2 := tt.RequestAuthGet[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId)) + tt.AssertEqual(t, "Confirmed", false, subAfter2.Confirmed) + tt.AssertEqual(t, "ChannelId", chan1.ChannelId, subAfter2.ChannelId) + tt.AssertEqual(t, "SubscriberUserId", data1.UID, subAfter2.SubscriberUserId) + tt.AssertEqual(t, "ChannelOwnerUserId", data2.UID, subAfter2.ChannelOwnerUserId) + } + } +} + +func TestCancelIncomingSubscription(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + } + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthDelete[tt.Void](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId), gin.H{}) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + tt.RequestAuthGetShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), 404, apierr.SUBSCRIPTION_NOT_FOUND) + } +} + +func TestCancelOutgoingSubscription(t *testing.T) { + ws, baseUrl, stop := tt.StartSimpleWebserver(t) + defer stop() + + data1 := tt.InitSingleData(t, ws) + data2 := tt.InitSingleData(t, ws) + + 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 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"` + } + + chan1 := tt.RequestAuthPost[chanobj](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels", data2.UID), gin.H{ + "name": "Chan1", + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + } + + sub1 := tt.RequestAuthPost[subobj](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions?chan_subscribe_key=%s", data1.UID, chan1.SubscribeKey), gin.H{ + "channel_id": chan1.ChannelId, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthPatch[gin.H](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data2.UID, sub1.SubscriptionId), gin.H{ + "confirmed": true, + }) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 2, len(slist.Subscriptions)) + } + + tt.RequestAuthDelete[tt.Void](t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), gin.H{}) + + { + slist := tt.RequestAuthGet[sublist](t, data2.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/channels/%s/subscriptions", data2.UID, chan1.ChannelId)) + tt.AssertEqual(t, "channel.subs.len", 1, len(slist.Subscriptions)) + tt.RequestAuthGetShouldFail(t, data1.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/subscriptions/%s", data1.UID, sub1.SubscriptionId), 404, apierr.SUBSCRIPTION_NOT_FOUND) + } } diff --git a/scnserver/test/util/factory.go b/scnserver/test/util/factory.go index a3c531c..104cda3 100644 --- a/scnserver/test/util/factory.go +++ b/scnserver/test/util/factory.go @@ -422,7 +422,7 @@ func InitDefaultData(t *testing.T, ws *logic.Application) DefData { } type SingleData struct { - UserID string + UID string AdminKey string SendKey string ReadKey string @@ -464,7 +464,7 @@ func InitSingleData(t *testing.T, ws *logic.Application) SingleData { success = true return SingleData{ - UserID: r0.UserId, + UID: r0.UserId, AdminKey: r0.AdminKey, SendKey: r0.SendKey, ReadKey: r0.ReadKey,