Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions apps/backend/internal/services/graph/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package graph

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/goddhi/ucan-visualizer/test/fixtures"
)

func TestGenerateDelegationGraph(t *testing.T) {
svc := NewService()

t.Run("Generates nodes and edges for chain", func(t *testing.T) {
tokenBytes, err := fixtures.GenerateComplexChain()
require.NoError(t, err)

graph, err := svc.GenerateDelegationGraph(tokenBytes)
require.NoError(t, err)

assert.GreaterOrEqual(t, len(graph.Nodes), 2)

hasRoot := false
hasLeaf := false
for _, node := range graph.Nodes {
if node.Type == "root" { hasRoot = true }
if node.Type == "leaf" { hasLeaf = true }
}
assert.True(t, hasRoot, "Graph must have a root node")
assert.True(t, hasLeaf, "Graph must have a leaf node")

assert.NotEmpty(t, graph.Edges)
assert.Equal(t, "delegation", graph.Edges[0].Type)
})
}

func TestGenerateInvocationGraph(t *testing.T) {
svc := NewService()

t.Run("Identifies delegation as NOT invocation", func(t *testing.T) {
tokenBytes, err := fixtures.GenerateValidUCAN()
require.NoError(t, err)

graph, err := svc.GenerateInvocationGraph(tokenBytes)
require.NoError(t, err)

assert.False(t, graph.IsInvocation)
assert.NotEmpty(t, graph.Nodes)
})
}
52 changes: 52 additions & 0 deletions apps/backend/internal/services/parser/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package parser

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/goddhi/ucan-visualizer/test/fixtures"
)

func TestParseDelegation(t *testing.T) {
svc := NewService()

t.Run("Successfully parses valid CAR token", func(t *testing.T) {
tokenBytes, err := fixtures.GenerateValidUCAN()
require.NoError(t, err)

result, err := svc.ParseDelegation(tokenBytes)

require.NoError(t, err)
assert.NotEmpty(t, result.CID)
assert.NotEmpty(t, result.Issuer)
assert.NotEmpty(t, result.Audience)

assert.Greater(t, len(result.Capabilities), 0)
assert.Equal(t, "store/add", result.Capabilities[0].Can)
})

t.Run("Fails on garbage input", func(t *testing.T) {
garbageBytes := []byte("this is not a real UCAN")

result, err := svc.ParseDelegation(garbageBytes)

assert.Error(t, err)
assert.Nil(t, result)
assert.Contains(t, err.Error(), "failed to decode")
})
}

func TestParseDelegationChain(t *testing.T) {
svc := NewService()

t.Run("Parses multi-hop chain", func(t *testing.T) {
chainBytes, err := fixtures.GenerateComplexChain()
require.NoError(t, err)

chain, err := svc.ParseDelegationChain(chainBytes)

require.NoError(t, err)
assert.NotEmpty(t, chain)
})
}
61 changes: 61 additions & 0 deletions apps/backend/internal/services/validator/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package validator

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/goddhi/ucan-visualizer/test/fixtures"
)

func TestValidateChain(t *testing.T) {
svc := NewService()

t.Run("Validates chain", func(t *testing.T) {
tokenBytes, err := fixtures.GenerateComplexChain()
require.NoError(t, err)

result, err := svc.ValidateChain(tokenBytes)
require.NoError(t, err)

assert.True(t, result.Valid)
assert.Equal(t, 0, result.Summary.InvalidLinks)
assert.Nil(t, result.RootCause)

assert.GreaterOrEqual(t, len(result.Chain), 1)
})

t.Run("Detects expired tokens", func(t *testing.T) {
tokenBytes, err := fixtures.GenerateExpiredUCAN()
require.NoError(t, err)

result, err := svc.ValidateChain(tokenBytes)
require.NoError(t, err)

assert.False(t, result.Valid)
assert.NotNil(t, result.RootCause)
assert.Equal(t, "expired", result.RootCause.Type)
assert.Contains(t, result.RootCause.Message, "UCAN expired")
})
}

func TestResourceMatching(t *testing.T) {
svc := NewService()

tests := []struct {
parent string
child string
expected bool
}{
{"storage:*", "storage:alice/photos", true},
{"storage:alice/*", "storage:alice/photos", true},
{"storage:alice/*", "storage:bob/photos", false},
{"*", "anything", true},
}

for _, tt := range tests {
t.Run(tt.parent+" -> "+tt.child, func(t *testing.T) {
assert.Equal(t, tt.expected, svc.resourceMatches(tt.parent, tt.child))
})
}
}
70 changes: 70 additions & 0 deletions apps/backend/pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package utils

import (
"encoding/base64"
"testing"

"github.com/stretchr/testify/assert"
)

func TestShortenDID(t *testing.T) {
tests := []struct {
input string
expected string
}{
{
"did:key:z6MkhaXgBZDnaWnM",
"did:key:z6MkhaXgBZDnaWnM", // Short enough,
},
{
"did:key:z6MkhaXgBZDnaWnMz6MkhaXgBZDnaWnMz6MkhaXgBZDnaWnM",
"did:key:z6MkhaXg...gBZDnaWnM", // Should truncate
},
}

for _, tt := range tests {
assert.Equal(t, tt.expected, ShortenDID(tt.input))
}
}

func TestNormalizeToken(t *testing.T) {
raw := []byte("raw-token-data")
encoded := base64.StdEncoding.EncodeToString(raw)

t.Run("Decodes Base64 explicit", func(t *testing.T) {
res, err := NormalizeToken(encoded, "base64")
assert.NoError(t, err)
assert.Equal(t, raw, res)
})

t.Run("Auto-detects Base64 in Raw", func(t *testing.T) {
res, err := NormalizeToken(encoded, "raw")
assert.NoError(t, err)
assert.Equal(t, raw, res)
})

t.Run("Handles plain raw string", func(t *testing.T) {
// If it's not base64, it should return as is
res, err := NormalizeToken("not-base-64", "raw")
assert.NoError(t, err)
assert.Equal(t, []byte("not-base-64"), res)
})
}

func TestValidateTokenFormat(t *testing.T) {
t.Run("Rejects empty", func(t *testing.T) {
err := ValidateTokenFormat("")
assert.Error(t, err)
})

t.Run("Rejects too short", func(t *testing.T) {
err := ValidateTokenFormat("abc")
assert.Error(t, err)
})

t.Run("Accepts valid base64", func(t *testing.T) {
valid := base64.StdEncoding.EncodeToString([]byte("valid-token-content"))
err := ValidateTokenFormat(valid)
assert.NoError(t, err)
})
}
Loading