* refactor: update api and client to reference humanIds * fix: prevent deletion of network member This may cause various side effects if there is data in other services which reference this member
177 lines
5.2 KiB
Go
177 lines
5.2 KiB
Go
package network_test
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/flowy-live/llink/internal/network"
|
|
"github.com/flowy-live/llink/internal/testhelper"
|
|
"github.com/jackc/pgx/v5/pgxpool"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
var dbPool *pgxpool.Pool
|
|
|
|
func TestMain(m *testing.M) {
|
|
dbPool = testhelper.SetupTestDB()
|
|
defer testhelper.TeardownTestDB()
|
|
|
|
ret := m.Run()
|
|
os.Exit(ret)
|
|
}
|
|
|
|
func TestNetworkService(t *testing.T) {
|
|
ctx := context.Background()
|
|
svc := network.NewService(dbPool)
|
|
|
|
adminHumanId := "human_admin123"
|
|
member1HumanId := "human_member1abc"
|
|
member2HumanId := "human_member2def"
|
|
strangerHumanId := "human_stranger789"
|
|
|
|
// Test Create
|
|
createdNetwork, err := svc.Create(ctx, "Test Network", adminHumanId)
|
|
assert.NoError(t, err)
|
|
assert.NotEmpty(t, createdNetwork.ID)
|
|
assert.Equal(t, "Test Network", createdNetwork.Name)
|
|
assert.Equal(t, adminHumanId, createdNetwork.AdminHumanId)
|
|
assert.NotZero(t, createdNetwork.CreatedAt)
|
|
|
|
// Test GetByID
|
|
foundNetwork, err := svc.GetByID(ctx, createdNetwork.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, createdNetwork.ID, foundNetwork.ID)
|
|
assert.Equal(t, createdNetwork.Name, foundNetwork.Name)
|
|
assert.Equal(t, createdNetwork.AdminHumanId, foundNetwork.AdminHumanId)
|
|
|
|
// Test GetByID with non-existent id
|
|
_, err = svc.GetByID(ctx, "network_nonexistent")
|
|
assert.Error(t, err)
|
|
assert.ErrorIs(t, err, network.ErrNotFound)
|
|
|
|
// Test SetName
|
|
err = svc.SetName(ctx, createdNetwork.ID, "Updated Network Name")
|
|
assert.NoError(t, err)
|
|
|
|
// Verify name was updated
|
|
updatedNetwork, err := svc.GetByID(ctx, createdNetwork.ID)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "Updated Network Name", updatedNetwork.Name)
|
|
|
|
// Test SetName with non-existent id
|
|
err = svc.SetName(ctx, "network_nonexistent", "New Name")
|
|
assert.Error(t, err)
|
|
assert.ErrorIs(t, err, network.ErrNotFound)
|
|
|
|
// Test AddMembers
|
|
err = svc.AddMembers(ctx, createdNetwork.ID, []string{member1HumanId, member2HumanId})
|
|
assert.NoError(t, err)
|
|
|
|
// Test ListForHuman - should find network for admin
|
|
networks, err := svc.ListForHuman(ctx, adminHumanId)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, networks, 1)
|
|
assert.Equal(t, createdNetwork.ID, networks[0].ID)
|
|
|
|
// Test ListForHuman - should find network for member
|
|
networks, err = svc.ListForHuman(ctx, member1HumanId)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, networks, 1)
|
|
assert.Equal(t, createdNetwork.ID, networks[0].ID)
|
|
|
|
// Test ListForHuman - should return empty for non-member
|
|
networks, err = svc.ListForHuman(ctx, strangerHumanId)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, networks, 0)
|
|
|
|
// Test RemoveMember
|
|
err = svc.RemoveMember(ctx, createdNetwork.ID, member1HumanId)
|
|
assert.NoError(t, err)
|
|
|
|
// Verify member was removed
|
|
networks, err = svc.ListForHuman(ctx, member1HumanId)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, networks, 0)
|
|
|
|
// member2 should still have access
|
|
networks, err = svc.ListForHuman(ctx, member2HumanId)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, networks, 1)
|
|
|
|
// Create another network and verify ListForHuman returns multiple
|
|
network2, err := svc.Create(ctx, "Second Network", member2HumanId)
|
|
assert.NoError(t, err)
|
|
|
|
networks, err = svc.ListForHuman(ctx, member2HumanId)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, networks, 2)
|
|
|
|
// Verify both networks are returned
|
|
networkIDs := []string{networks[0].ID, networks[1].ID}
|
|
assert.Contains(t, networkIDs, createdNetwork.ID)
|
|
assert.Contains(t, networkIDs, network2.ID)
|
|
}
|
|
|
|
func TestNetworkInvitations(t *testing.T) {
|
|
ctx := context.Background()
|
|
svc := network.NewService(dbPool)
|
|
|
|
adminHumanId := "human_invtest_admin"
|
|
inviteeEmail := "[email protected]"
|
|
inviteeHumanId := "human_invitee123"
|
|
|
|
// Create a network
|
|
net, err := svc.Create(ctx, "Invitation Test Network", adminHumanId)
|
|
assert.NoError(t, err)
|
|
|
|
// Invite by email
|
|
err = svc.InviteByEmail(ctx, net.ID, []string{inviteeEmail})
|
|
assert.NoError(t, err)
|
|
|
|
// List invitations for email
|
|
invitations, err := svc.ListInvitationsForEmail(ctx, inviteeEmail)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, invitations, 1)
|
|
assert.Equal(t, net.ID, invitations[0].NetworkID)
|
|
assert.Equal(t, inviteeEmail, invitations[0].Email)
|
|
|
|
// List invitations for network
|
|
invitations, err = svc.ListInvitationsForNetwork(ctx, net.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, invitations, 1)
|
|
|
|
// Duplicate invite is idempotent
|
|
err = svc.InviteByEmail(ctx, net.ID, []string{inviteeEmail})
|
|
assert.NoError(t, err)
|
|
invitations, err = svc.ListInvitationsForNetwork(ctx, net.ID)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, invitations, 1)
|
|
|
|
// Accept invitation
|
|
err = svc.AcceptInvitation(ctx, net.ID, inviteeEmail, inviteeHumanId)
|
|
assert.NoError(t, err)
|
|
|
|
// Invitation should be removed
|
|
invitations, err = svc.ListInvitationsForEmail(ctx, inviteeEmail)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, invitations, 0)
|
|
|
|
// Human should now be a member
|
|
isMember, err := svc.IsMember(ctx, net.ID, inviteeHumanId)
|
|
assert.NoError(t, err)
|
|
assert.True(t, isMember)
|
|
|
|
// Test revoke invitation
|
|
revokeEmail := "[email protected]"
|
|
err = svc.InviteByEmail(ctx, net.ID, []string{revokeEmail})
|
|
assert.NoError(t, err)
|
|
|
|
err = svc.RevokeInvitation(ctx, net.ID, revokeEmail)
|
|
assert.NoError(t, err)
|
|
|
|
invitations, err = svc.ListInvitationsForEmail(ctx, revokeEmail)
|
|
assert.NoError(t, err)
|
|
assert.Len(t, invitations, 0)
|
|
}
|