Files
sub2api/backend/internal/service/api_key_group_visibility_test.go
T

101 lines
3.3 KiB
Go

//go:build unit
package service
import (
"context"
"errors"
"testing"
"time"
"github.com/stretchr/testify/require"
)
type visibilityUserRepo struct {
UserRepository
user *User
err error
}
func (r *visibilityUserRepo) GetByID(context.Context, int64) (*User, error) { return r.user, r.err }
type visibilitySubRepo struct {
UserSubscriptionRepository
subscriptions []UserSubscription
err error
calls int
}
func (r *visibilitySubRepo) ListActiveByUserID(_ context.Context, userID int64) ([]UserSubscription, error) {
r.calls++
// Match the repository's active-status and expiry predicates.
active := make([]UserSubscription, 0)
for _, sub := range r.subscriptions {
if sub.UserID == userID && sub.IsActive() {
active = append(active, sub)
}
}
return active, r.err
}
type visibilityGroupRepo struct {
GroupRepository
groups []Group
}
func (r *visibilityGroupRepo) ListActive(context.Context) ([]Group, error) { return r.groups, nil }
func TestGetUserGroupVisibilityIncludesActiveSubscriptions(t *testing.T) {
for _, restricted := range []bool{false, true} {
t.Run(map[bool]string{false: "unrestricted", true: "restricted"}[restricted], func(t *testing.T) {
now := time.Now()
subs := &visibilitySubRepo{subscriptions: []UserSubscription{
{UserID: 1, GroupID: 42, Status: SubscriptionStatusActive, ExpiresAt: now.Add(time.Hour)},
{UserID: 1, GroupID: 43, Status: SubscriptionStatusActive, ExpiresAt: now.Add(-time.Hour)},
{UserID: 1, GroupID: 44, Status: "expired", ExpiresAt: now.Add(time.Hour)},
{UserID: 2, GroupID: 45, Status: SubscriptionStatusActive, ExpiresAt: now.Add(time.Hour)},
}}
svc := &APIKeyService{
userRepo: &visibilityUserRepo{user: &User{ID: 1, AllowedGroups: []int64{7}, RestrictPublicGroups: restricted}},
userSubRepo: subs,
groupRepo: &visibilityGroupRepo{groups: []Group{{ID: 42, IsExclusive: true, SubscriptionType: "subscription"}}},
}
available, err := svc.GetAvailableGroups(context.Background(), 1)
require.NoError(t, err)
require.Len(t, available, 1)
visible, restrict, err := svc.GetUserGroupVisibility(context.Background(), 1)
require.NoError(t, err)
require.Equal(t, restricted, restrict)
require.Equal(t, map[int64]struct{}{7: {}, 42: {}}, visible)
require.Contains(t, visible, available[0].ID, "a subscribed group that can be bound must be visible")
})
}
}
func TestGetUserGroupVisibilityEmptyAndErrors(t *testing.T) {
failure := errors.New("repository unavailable")
for _, tc := range []struct {
name string
userErr, subErr error
}{
{name: "empty"}, {name: "user failure", userErr: failure}, {name: "subscription failure", subErr: failure},
} {
t.Run(tc.name, func(t *testing.T) {
subs := &visibilitySubRepo{err: tc.subErr}
svc := &APIKeyService{userRepo: &visibilityUserRepo{user: &User{ID: 1}, err: tc.userErr}, userSubRepo: subs}
got, _, err := svc.GetUserGroupVisibility(context.Background(), 1)
if tc.userErr != nil || tc.subErr != nil {
require.ErrorIs(t, err, failure)
require.Nil(t, got, "repository failures must not become anonymous visibility")
} else {
require.NoError(t, err)
require.NotNil(t, got, "an empty logged-in user must not become anonymous")
require.Empty(t, got)
}
if tc.userErr != nil {
require.Zero(t, subs.calls)
}
})
}
}