Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reusable test vectors #130

Merged
merged 7 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 4 additions & 0 deletions vc/vcjwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ func Decode[T CredentialSubject](vcJWT string) (DecodedVCJWT[T], error) {
return DecodedVCJWT[T]{}, fmt.Errorf("failed to decode vc claim: %w", err)
}

if vc.Type == nil {
return DecodedVCJWT[T]{}, errors.New("vc-jwt missing vc type")
}

// the following conditionals are included to conform with the jwt decoding section
// of the specification defined here: https://www.w3.org/TR/vc-data-model/#jwt-decoding
if decoded.Claims.Issuer != "" {
Expand Down
24 changes: 24 additions & 0 deletions vc/vcjwt_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package vc_test

import (
"fmt"
"testing"
"time"

"github.com/alecthomas/assert/v2"
web5go "github.com/tbd54566975/web5-go"
"github.com/tbd54566975/web5-go/dids/didjwk"
"github.com/tbd54566975/web5-go/jwt"
"github.com/tbd54566975/web5-go/vc"
Expand Down Expand Up @@ -82,6 +84,7 @@ func TestDecode_SetClaims(t *testing.T) {
Misc: map[string]any{
"vc": vc.DataModel[vc.Claims]{
CredentialSubject: subjectClaims,
Type: []string{"Something"},
},
},
}
Expand Down Expand Up @@ -164,3 +167,24 @@ func TestVerify(t *testing.T) {
})
}
}

func TestVector_Decode(t *testing.T) {
testVectors, err :=
web5go.ReadTestVector[string, any]("../web5-spec/test-vectors/vc_jwt/decode.json")
assert.NoError(t, err)
fmt.Println("Running test vectors: ", testVectors.Description)

for _, vector := range testVectors.Vectors {
t.Run(vector.Description, func(t *testing.T) {
fmt.Println("Running test vector: ", vector.Description)

_, err := vc.Decode[vc.Claims](vector.Input)

if vector.Errors {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
36 changes: 36 additions & 0 deletions web5-spec-test-vectors.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

he done it! he used the dashes! the thing everyone wants to do but shys away bc presumed go convention. thoughts on just testvectors.go? are you thinking we may end up adding moar vector loaders? if so, adding web5-spec def makes sense as prefix. alternatively, could use this file for loading all sorts of vectors and change the function name to LoadWeb5SpecVectors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oop, been in rust hacking land so forgetting golang conventions, change the filename!

thought about making the function specific to web5, but that data structure may be a standard or reusable across different vector sets, so leaving as-is for now

a bit annoying we have the relative file path in the test file but I can't think of an obvious better alternative

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package web5go
KendallWeihe marked this conversation as resolved.
Show resolved Hide resolved

import (
"encoding/json"
"os"
)

// TestVectors are JSON files which are tested against to ensure interop with the specification
type TestVectors[T, U any] struct {
Description string `json:"description"`
Vectors []TestVector[T, U] `json:"vectors"`
}

// TestVector is an individual test vector case
type TestVector[T, U any] struct {
Description string `json:"description"`
Input T `json:"input"`
Output U `json:"output"`
Errors bool `json:"errors"`
}

// ReadTestVector is for reading the vector at the given path
func ReadTestVector[T, U any](path string) (TestVectors[T, U], error) {
KendallWeihe marked this conversation as resolved.
Show resolved Hide resolved
data, err := os.ReadFile(path)
if err != nil {
return TestVectors[T, U]{}, err
}

var testVectors TestVectors[T, U]
err = json.Unmarshal(data, &testVectors)
if err != nil {
return TestVectors[T, U]{}, err
}

return testVectors, nil
}
Loading