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  }