github.com/hyperledger/aries-framework-go@v0.3.2/pkg/store/did/store_test.go (about) 1 /* 2 Copyright SecureKey Technologies Inc. All Rights Reserved. 3 SPDX-License-Identifier: Apache-2.0 4 */ 5 6 package did_test 7 8 import ( 9 "crypto/ed25519" 10 "crypto/rand" 11 "fmt" 12 "strconv" 13 "testing" 14 "time" 15 16 "github.com/btcsuite/btcutil/base58" 17 "github.com/stretchr/testify/require" 18 19 "github.com/hyperledger/aries-framework-go/component/storageutil/mem" 20 "github.com/hyperledger/aries-framework-go/pkg/common/model" 21 "github.com/hyperledger/aries-framework-go/pkg/doc/did" 22 mockprovider "github.com/hyperledger/aries-framework-go/pkg/mock/provider" 23 mockstore "github.com/hyperledger/aries-framework-go/pkg/mock/storage" 24 didstore "github.com/hyperledger/aries-framework-go/pkg/store/did" 25 ) 26 27 const ( 28 sampleDIDName = "sampleDIDName" 29 sampleDIDID = "sampleDIDID" 30 ) 31 32 func TestNew(t *testing.T) { 33 t.Run("test new store", func(t *testing.T) { 34 s, err := didstore.New(&mockprovider.Provider{ 35 StorageProviderValue: mem.NewProvider(), 36 }) 37 require.NoError(t, err) 38 require.NotNil(t, s) 39 }) 40 41 t.Run("test error from open store", func(t *testing.T) { 42 s, err := didstore.New(&mockprovider.Provider{ 43 StorageProviderValue: &mockstore.MockStoreProvider{ 44 ErrOpenStoreHandle: fmt.Errorf("failed to open store"), 45 }, 46 }) 47 require.Error(t, err) 48 require.Contains(t, err.Error(), "failed to open store") 49 require.Nil(t, s) 50 }) 51 } 52 53 func TestSaveDID(t *testing.T) { 54 t.Run("test save did doc - success", func(t *testing.T) { 55 s, err := didstore.New(&mockprovider.Provider{ 56 StorageProviderValue: mockstore.NewMockStoreProvider(), 57 }) 58 require.NoError(t, err) 59 require.NoError(t, s.SaveDID(sampleDIDName, &did.Doc{ID: "did1"})) 60 }) 61 62 t.Run("test save did doc - error from store put", func(t *testing.T) { 63 s, err := didstore.New(&mockprovider.Provider{ 64 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 65 Store: make(map[string]mockstore.DBEntry), 66 ErrPut: fmt.Errorf("error put"), 67 }), 68 }) 69 require.NoError(t, err) 70 err = s.SaveDID(sampleDIDName, &did.Doc{ID: "did1"}) 71 require.Error(t, err) 72 require.Contains(t, err.Error(), "error put") 73 }) 74 75 t.Run("test save did doc - empty name", func(t *testing.T) { 76 s, err := didstore.New(&mockprovider.Provider{ 77 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 78 Store: make(map[string]mockstore.DBEntry), 79 ErrPut: fmt.Errorf("error put"), 80 }), 81 }) 82 require.NoError(t, err) 83 err = s.SaveDID("", &did.Doc{ID: "did1"}) 84 require.Error(t, err) 85 require.Contains(t, err.Error(), "did name is mandatory") 86 }) 87 88 t.Run("test save did doc - error getting existing mapping for name", func(t *testing.T) { 89 s, err := didstore.New(&mockprovider.Provider{ 90 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 91 Store: make(map[string]mockstore.DBEntry), 92 ErrGet: fmt.Errorf("error get"), 93 }), 94 }) 95 require.NoError(t, err) 96 err = s.SaveDID(sampleDIDName, &did.Doc{ID: "did1"}) 97 require.Error(t, err) 98 require.Contains(t, err.Error(), "get did using name") 99 }) 100 101 t.Run("test save did doc - name already exists", func(t *testing.T) { 102 s, err := didstore.New(&mockprovider.Provider{ 103 StorageProviderValue: mockstore.NewMockStoreProvider(), 104 }) 105 require.NoError(t, err) 106 require.NoError(t, s.SaveDID(sampleDIDName, &did.Doc{ID: "did1"})) 107 108 err = s.SaveDID(sampleDIDName, &did.Doc{ID: "did2"}) 109 require.Error(t, err) 110 require.Contains(t, err.Error(), "did name already exists") 111 }) 112 } 113 114 func TestGetDIDDoc(t *testing.T) { 115 t.Run("test success", func(t *testing.T) { 116 s, err := didstore.New(&mockprovider.Provider{ 117 StorageProviderValue: mockstore.NewMockStoreProvider(), 118 }) 119 require.NoError(t, err) 120 didDoc := createDIDDoc() 121 require.NoError(t, s.SaveDID(sampleDIDName, didDoc)) 122 doc, err := s.GetDID((didDoc.ID)) 123 require.NoError(t, err) 124 require.Equal(t, doc.ID, didDoc.ID) 125 }) 126 127 t.Run("test error from store get", func(t *testing.T) { 128 s, err := didstore.New(&mockprovider.Provider{ 129 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 130 Store: make(map[string]mockstore.DBEntry), 131 ErrGet: fmt.Errorf("error get"), 132 }), 133 }) 134 require.NoError(t, err) 135 didDoc, err := s.GetDID("did1") 136 require.Error(t, err) 137 require.Contains(t, err.Error(), "error get") 138 require.Nil(t, didDoc) 139 }) 140 141 t.Run("test error data not found", func(t *testing.T) { 142 s, err := didstore.New(&mockprovider.Provider{ 143 StorageProviderValue: mockstore.NewMockStoreProvider(), 144 }) 145 require.NoError(t, err) 146 require.NoError(t, s.SaveDID(sampleDIDName, &did.Doc{ID: "did1"})) 147 require.NoError(t, err) 148 didDoc, err := s.GetDID("did12") 149 require.Error(t, err) 150 require.Contains(t, err.Error(), "data not found") 151 require.Nil(t, didDoc) 152 }) 153 } 154 155 func TestDIDBasedOnName(t *testing.T) { 156 t.Run("test get didDoc based on name - success", func(t *testing.T) { 157 store := make(map[string]mockstore.DBEntry) 158 store[didNameDataKey(sampleDIDName)] = mockstore.DBEntry{Value: []byte(sampleDIDID)} 159 160 s, err := didstore.New(&mockprovider.Provider{ 161 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 162 }) 163 require.NoError(t, err) 164 165 id, err := s.GetDIDByName(sampleDIDName) 166 require.NoError(t, err) 167 require.Equal(t, sampleDIDID, id) 168 }) 169 170 t.Run("test get didDoc based on name - db error", func(t *testing.T) { 171 s, err := didstore.New(&mockprovider.Provider{ 172 StorageProviderValue: mockstore.NewCustomMockStoreProvider(&mockstore.MockStore{ 173 Store: make(map[string]mockstore.DBEntry), 174 ErrGet: fmt.Errorf("error get"), 175 }), 176 }) 177 require.NoError(t, err) 178 179 id, err := s.GetDIDByName(sampleDIDName) 180 require.Error(t, err) 181 require.Contains(t, err.Error(), "fetch did doc id based on name") 182 require.Equal(t, "", id) 183 }) 184 } 185 186 func TestGetCredentials(t *testing.T) { 187 t.Run("test get dids", func(t *testing.T) { 188 store := make(map[string]mockstore.DBEntry) 189 s, err := didstore.New(&mockprovider.Provider{ 190 StorageProviderValue: &mockstore.MockStoreProvider{Store: &mockstore.MockStore{Store: store}}, 191 }) 192 require.NoError(t, err) 193 194 records := s.GetDIDRecords() 195 require.Equal(t, 0, len(records)) 196 197 err = s.SaveDID(sampleDIDName, &did.Doc{ID: sampleDIDID}) 198 require.NoError(t, err) 199 200 records = s.GetDIDRecords() 201 require.Equal(t, 1, len(records)) 202 require.Equal(t, records[0].Name, sampleDIDName) 203 require.Equal(t, records[0].ID, sampleDIDID) 204 205 // add some other values and make sure the GetCredential returns records as before 206 store["dummy-value"] = mockstore.DBEntry{Value: []byte("dummy-key")} 207 208 records = s.GetDIDRecords() 209 require.Equal(t, 1, len(records)) 210 211 n := 10 212 for i := 0; i < n; i++ { 213 err = s.SaveDID(sampleDIDName+strconv.Itoa(i), 214 &did.Doc{ID: sampleDIDID + strconv.Itoa(i)}) 215 require.NoError(t, err) 216 } 217 218 records = s.GetDIDRecords() 219 require.Equal(t, 1+n, len(records)) 220 }) 221 } 222 223 func didNameDataKey(name string) string { 224 return fmt.Sprintf("didname_%s", name) 225 } 226 227 func createDIDDoc() *did.Doc { 228 pubKey, _ := generateKeyPair() 229 return createDIDDocWithKey(pubKey) 230 } 231 232 func generateKeyPair() (string, []byte) { 233 pubKey, privKey, err := ed25519.GenerateKey(rand.Reader) 234 if err != nil { 235 panic(err) 236 } 237 238 return base58.Encode(pubKey[:]), privKey 239 } 240 241 func createDIDDocWithKey(pub string) *did.Doc { 242 const ( 243 didFormat = "did:%s:%s" 244 didPKID = "%s#keys-%d" 245 didServiceID = "%s#endpoint-%d" 246 method = "test" 247 ) 248 249 id := fmt.Sprintf(didFormat, method, pub[:16]) 250 pubKeyID := fmt.Sprintf(didPKID, id, 1) 251 pubKey := did.VerificationMethod{ 252 ID: pubKeyID, 253 Type: "Ed25519VerificationKey2018", 254 Controller: id, 255 Value: []byte(pub), 256 } 257 services := []did.Service{ 258 { 259 ID: fmt.Sprintf(didServiceID, id, 1), 260 Type: "did-communication", 261 ServiceEndpoint: model.NewDIDCommV1Endpoint("http://localhost:58416"), 262 Priority: 0, 263 RecipientKeys: []string{pubKeyID}, 264 }, 265 } 266 createdTime := time.Now() 267 didDoc := &did.Doc{ 268 Context: []string{did.ContextV1}, 269 ID: id, 270 VerificationMethod: []did.VerificationMethod{pubKey}, 271 Service: services, 272 Created: &createdTime, 273 Updated: &createdTime, 274 } 275 276 return didDoc 277 }