github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/profile/store_test.go (about) 1 package profile 2 3 import ( 4 "context" 5 "encoding/json" 6 "errors" 7 "io/ioutil" 8 "os" 9 "path/filepath" 10 "testing" 11 "time" 12 13 "github.com/google/go-cmp/cmp" 14 "github.com/google/go-cmp/cmp/cmpopts" 15 "github.com/libp2p/go-libp2p-core/peer" 16 crypto "github.com/libp2p/go-libp2p-crypto" 17 "github.com/qri-io/qri/auth/key" 18 testkeys "github.com/qri-io/qri/auth/key/test" 19 "github.com/qri-io/qri/config" 20 ) 21 22 func TestPutProfileWithAddresses(t *testing.T) { 23 ctx := context.Background() 24 pp := &config.ProfilePod{ 25 ID: "QmU27VdAEUL5NGM6oB56htTxvHLfcGZgsgxrJTdVr2k4zs", 26 Peername: "test_peername", 27 Created: time.Unix(1234567890, 0).In(time.UTC), 28 Updated: time.Unix(1234567890, 0).In(time.UTC), 29 } 30 pro, err := NewProfile(pp) 31 if err != nil { 32 t.Errorf("error creating new profile: %s", err.Error()) 33 } 34 pid, _ := peer.IDB58Decode("Qmb9Gy14GuCjrhRSjGJQpf5JkgdEdbZrV81Tz4x3ZDreY3") 35 pro.PeerIDs = []peer.ID{ 36 pid, 37 } 38 39 path := filepath.Join(os.TempDir(), "profile") 40 if err := os.MkdirAll(path, os.ModePerm); err != nil { 41 t.Errorf("error creating tmp directory: %s", err.Error()) 42 } 43 44 kd0 := testkeys.GetKeyData(0) 45 46 ks, err := key.NewMemStore() 47 if err != nil { 48 t.Fatal(err) 49 } 50 51 owner := &Profile{ 52 ID: IDFromPeerID(kd0.PeerID), 53 Peername: "user", 54 PrivKey: kd0.PrivKey, 55 } 56 ps, err := NewLocalStore(ctx, filepath.Join(path, "profiles.json"), owner, ks) 57 if err != nil { 58 t.Fatal(err) 59 } 60 61 err = ps.PutProfile(ctx, pro) 62 if err != nil { 63 t.Errorf("error putting profile: %s", err.Error()) 64 } 65 66 goldenFilepath := "testdata/simple.json" 67 gf, err := ioutil.ReadFile(goldenFilepath) 68 if err != nil { 69 t.Errorf("error reading golden file: %s", err.Error()) 70 } 71 golden := map[string]interface{}{} 72 if err := json.Unmarshal(gf, &golden); err != nil { 73 t.Fatal(err) 74 } 75 76 path = filepath.Join(path, "profiles.json") 77 f, err := ioutil.ReadFile(path) 78 if err != nil { 79 t.Errorf("error reading written file: %s", err.Error()) 80 } 81 got := map[string]interface{}{} 82 if err := json.Unmarshal(f, &got); err != nil { 83 t.Fatal(err) 84 } 85 86 t.Log(string(f)) 87 if diff := cmp.Diff(golden, got); diff != "" { 88 t.Errorf("result mismatch (-want +got):\n%s", diff) 89 } 90 } 91 92 func TestProfilesWithKeys(t *testing.T) { 93 ctx := context.Background() 94 kd0 := testkeys.GetKeyData(0) 95 96 ks, err := key.NewMemStore() 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 path := filepath.Join(os.TempDir(), "profile_keys") 102 if err := os.MkdirAll(path, os.ModePerm); err != nil { 103 t.Errorf("error creating tmp directory: %s", err.Error()) 104 } 105 106 owner := &Profile{ 107 ID: IDFromPeerID(kd0.PeerID), 108 Peername: "user", 109 PrivKey: kd0.PrivKey, 110 } 111 ps, err := NewLocalStore(ctx, filepath.Join(path, "profiles.json"), owner, ks) 112 if err != nil { 113 t.Fatal(err) 114 } 115 116 pp := &config.ProfilePod{ 117 ID: kd0.PeerID.String(), 118 Peername: "p0", 119 Created: time.Unix(1234567890, 0).In(time.UTC), 120 Updated: time.Unix(1234567890, 0).In(time.UTC), 121 } 122 pro, err := NewProfile(pp) 123 if err != nil { 124 t.Fatal(err) 125 } 126 127 pro.PrivKey = kd0.PrivKey 128 pro.PubKey = kd0.PrivKey.GetPublic() 129 130 err = ps.PutProfile(ctx, pro) 131 if err != nil { 132 t.Fatal(err) 133 } 134 135 tPro, err := ps.GetProfile(ctx, pro.ID) 136 if err != nil { 137 t.Fatal(err) 138 } 139 140 if !tPro.PrivKey.Equals(kd0.PrivKey) { 141 t.Fatalf("private keys don't match\ngot: %#v\nwant: %#v", tPro.PrivKey, kd0.PrivKey.GetPublic()) 142 } 143 144 if !tPro.PubKey.Equals(kd0.PrivKey.GetPublic()) { 145 t.Fatalf("public keys don't match.\ngot: %#v\nwant: %#v", tPro.PubKey, kd0.PrivKey.GetPublic()) 146 } 147 } 148 149 func TestMemStoreGetOwner(t *testing.T) { 150 ctx := context.Background() 151 kd0 := testkeys.GetKeyData(0) 152 id := IDFromPeerID(kd0.PeerID) 153 owner := &Profile{ID: id, PrivKey: kd0.PrivKey, Peername: "owner"} 154 ks, err := key.NewMemStore() 155 if err != nil { 156 t.Fatal(err) 157 } 158 159 s, err := NewMemStore(ctx, owner, ks) 160 if err != nil { 161 t.Fatal(err) 162 } 163 164 pro, err := s.GetProfile(ctx, id) 165 if err != nil { 166 t.Fatal(err) 167 } 168 169 if pro.PrivKey == nil { 170 t.Error("getting owner profile must return profile with private key populated") 171 } 172 173 if diff := cmp.Diff(owner, pro, cmpopts.IgnoreUnexported(Profile{}, crypto.RsaPublicKey{}, crypto.RsaPrivateKey{}, crypto.ECDSAPublicKey{}, crypto.ECDSAPrivateKey{})); diff != "" { 174 t.Errorf("get owner mismatch. (-want +got):\n%s", diff) 175 } 176 } 177 178 func TestResolveUsername(t *testing.T) { 179 ctx := context.Background() 180 kd0 := testkeys.GetKeyData(0) 181 kd1 := testkeys.GetKeyData(1) 182 kd2 := testkeys.GetKeyData(2) 183 184 ks, err := key.NewMemStore() 185 if err != nil { 186 t.Fatal(err) 187 } 188 189 owner := &Profile{ID: IDFromPeerID(kd0.PeerID), PrivKey: kd0.PrivKey, Peername: "owner"} 190 s, err := NewMemStore(ctx, owner, ks) 191 if err != nil { 192 t.Fatal(err) 193 } 194 195 if _, err := ResolveUsername(ctx, s, "unknown"); !errors.Is(err, ErrNotFound) { 196 t.Errorf("expected unknown username to return ErrNotFound or wrap of ErrNotFound. got: %#v", err) 197 } 198 199 pro, err := ResolveUsername(ctx, s, "owner") 200 if err != nil { 201 t.Error(err) 202 } 203 if diff := cmp.Diff(owner, pro, cmpopts.IgnoreUnexported(Profile{}, crypto.RsaPrivateKey{}, crypto.ECDSAPrivateKey{})); diff != "" { 204 t.Errorf("get owner mismatch. (-want +got):\n%s", diff) 205 } 206 207 marjorieA := &Profile{ID: IDFromPeerID(kd1.PeerID), PrivKey: kd1.PrivKey, Peername: "marjorie", Email: "marjorie_a@aol.com"} 208 marjorieB := &Profile{ID: IDFromPeerID(kd2.PeerID), PrivKey: kd2.PrivKey, Peername: "marjorie", Email: "marjorie_b@aol.com"} 209 210 if err := s.PutProfile(ctx, marjorieA); err != nil { 211 t.Fatal(err) 212 } 213 if err := s.PutProfile(ctx, marjorieB); err != nil { 214 t.Fatal(err) 215 } 216 217 if _, err := ResolveUsername(ctx, s, "marjorie"); !errors.Is(err, ErrAmbiguousUsername) { 218 t.Errorf("expected duplicated username to return ErrAmbiguousUsername or wrap of that error. got: %#v", err) 219 } 220 }