Skip to content
Snippets Groups Projects
Commit 82faa8e5 authored by Lyuben Penkovski's avatar Lyuben Penkovski
Browse files

Unit tests for rego funcs for proofs

parent 7bfdf095
No related branches found
No related tags found
1 merge request!34Extension functions for creating and verifying VC/VP proofs
Pipeline #52813 passed with stages
in 1 minute and 23 seconds
......@@ -191,7 +191,7 @@ func (sf *SignerFuncs) CreateProof() (*rego.Function, rego.Builtin1) {
defer resp.Body.Close() // nolint:errcheck
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected response from signer: %d", resp.StatusCode)
return nil, fmt.Errorf("unexpected response from signer: %s", resp.Status)
}
v, err := ast.ValueFromReader(resp.Body)
......@@ -256,7 +256,7 @@ func (sf *SignerFuncs) VerifyProof() (*rego.Function, rego.Builtin1) {
defer resp.Body.Close() // nolint:errcheck
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected response from signer: %d", resp.StatusCode)
return nil, fmt.Errorf("unexpected response from signer: %s", resp.Status)
}
var result struct {
......
......@@ -96,3 +96,154 @@ func TestIssuerDID(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, expected, string(resultBytes))
}
func TestCreateProof(t *testing.T) {
tests := []struct {
name string
input map[string]interface{}
signerResponseCode int
errtext string
}{
{
name: "missing credential type",
input: map[string]interface{}{"vc": "data"},
errtext: "credential data does not specify type",
},
{
name: "unknown credential type",
input: map[string]interface{}{"type": "non-existing-type"},
errtext: "unknown credential type",
},
{
name: "signer returns error for VC",
input: map[string]interface{}{"type": "VerifiableCredential"},
signerResponseCode: http.StatusBadRequest,
errtext: "400 Bad Request",
},
{
name: "signer returns error for VP",
input: map[string]interface{}{"type": "VerifiablePresentation"},
signerResponseCode: http.StatusBadRequest,
errtext: "400 Bad Request",
},
{
name: "signer returns successfully",
input: map[string]interface{}{"type": "VerifiableCredential"},
signerResponseCode: http.StatusOK,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
expected := `{"vc":"data"}`
signerSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(test.signerResponseCode)
_, _ = fmt.Fprint(w, expected)
}))
defer signerSrv.Close()
keysFuncs := regofunc.NewSignerFuncs(signerSrv.URL, http.DefaultClient)
query, err := rego.New(
rego.Query(`proof.create(input)`),
rego.Function1(keysFuncs.CreateProof()),
rego.StrictBuiltinErrors(true),
).PrepareForEval(context.Background())
assert.NoError(t, err)
resultSet, err := query.Eval(context.Background(), rego.EvalInput(test.input))
if err != nil {
assert.Contains(t, err.Error(), test.errtext)
} else {
assert.NotEmpty(t, resultSet)
assert.NotEmpty(t, resultSet[0].Expressions)
resultBytes, err := json.Marshal(resultSet[0].Expressions[0].Value)
assert.NoError(t, err)
assert.Equal(t, expected, string(resultBytes))
}
})
}
}
func TestVerifyProof(t *testing.T) {
tests := []struct {
name string
input map[string]interface{}
signerResponseCode int
errtext string
}{
{
name: "invalid credential",
input: nil,
errtext: "credential data does not specify type",
},
{
name: "missing credential type",
input: map[string]interface{}{"vc": "data"},
errtext: "credential data does not specify type",
},
{
name: "credential type is not string",
input: map[string]interface{}{"type": 123},
signerResponseCode: http.StatusBadRequest,
errtext: "invalid credential type, string is expected",
},
{
name: "missing proof section",
input: map[string]interface{}{"type": "VerifiableCredential"},
errtext: "credential data does contain proof section",
},
{
name: "unknown credential type",
input: map[string]interface{}{"proof": "iamhere", "type": "non-existing-type"},
errtext: "unknown credential type",
},
{
name: "signer returns error for VC",
input: map[string]interface{}{"proof": "iamhere", "type": "VerifiableCredential"},
signerResponseCode: http.StatusBadRequest,
errtext: "400 Bad Request",
},
{
name: "signer returns error for VP",
input: map[string]interface{}{"proof": "iamhere", "type": "VerifiablePresentation"},
signerResponseCode: http.StatusBadRequest,
errtext: "400 Bad Request",
},
{
name: "signer returns successfully",
input: map[string]interface{}{"proof": "iamhere", "type": "VerifiableCredential"},
signerResponseCode: http.StatusOK,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
expected := `{"valid":true}`
signerSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(test.signerResponseCode)
_, _ = fmt.Fprint(w, expected)
}))
defer signerSrv.Close()
keysFuncs := regofunc.NewSignerFuncs(signerSrv.URL, http.DefaultClient)
query, err := rego.New(
rego.Query(`proof.verify(input)`),
rego.Function1(keysFuncs.VerifyProof()),
rego.StrictBuiltinErrors(true),
).PrepareForEval(context.Background())
assert.NoError(t, err)
resultSet, err := query.Eval(context.Background(), rego.EvalInput(test.input))
if err != nil {
assert.NotEmpty(t, test.errtext, "test case must contain error, but doesn't")
assert.Contains(t, err.Error(), test.errtext)
} else {
assert.NotEmpty(t, resultSet)
assert.NotEmpty(t, resultSet[0].Expressions)
valid, ok := resultSet[0].Expressions[0].Value.(bool)
assert.True(t, ok)
assert.True(t, valid)
}
})
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment