1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package libkb
5
6import (
7	"testing"
8
9	keybase1 "github.com/keybase/client/go/protocol/keybase1"
10)
11
12type cidTest struct {
13	name      string
14	pgpUIDArg []string
15	errOut    error
16	idsOut    []Identity
17}
18
19var cidTests = []cidTest{
20	{"empty", []string{}, nil, []Identity{}},
21	{"no custom", []string{}, nil, []Identity{}},
22	{"one ID", []string{"pc@pc.com"}, nil, []Identity{
23		{Email: "pc@pc.com"},
24	}},
25	{"one ID with comment", []string{"non_email_name (test comment)"}, nil, []Identity{
26		{Username: "non_email_name", Comment: "test comment"},
27	}},
28	{"one email with comment", []string{"(test comment) <pc@pc.com>"}, nil, []Identity{
29		{Email: "pc@pc.com", Comment: "test comment"},
30	}},
31	{"custom", []string{"pc@pc.com"}, nil, []Identity{
32		{Email: "pc@pc.com"},
33	}},
34	{"many custom", []string{"pc@pc.com", "ab@ab.com", "cd@cd.com"}, nil, []Identity{
35		{Email: "pc@pc.com"},
36		{Email: "ab@ab.com"},
37		{Email: "cd@cd.com"},
38	}},
39	{"pgp uid", []string{"Patrick Crosby <pc@pc.com>"}, nil, []Identity{
40		{Username: "Patrick Crosby", Email: "pc@pc.com"},
41	}},
42	{"pgp uid no email", []string{"Patrick Crosby"}, nil, []Identity{
43		{Username: "Patrick Crosby"},
44	}},
45	{"brackets", []string{"<xyz@xyz.com>"}, nil, []Identity{
46		{Email: "xyz@xyz.com"},
47	}},
48	{"brackets with comment", []string{"(test comment) <xyz@xyz.com>"}, nil, []Identity{
49		{Email: "xyz@xyz.com", Comment: "test comment"},
50	}},
51	{"mixture", []string{"Patrick Crosby", "pc@pc.com", "<ab@ab.com>", "CD <cd@cd.com>"}, nil, []Identity{
52		{Username: "Patrick Crosby"},
53		{Email: "pc@pc.com"},
54		{Email: "ab@ab.com"},
55		{Username: "CD", Email: "cd@cd.com"},
56	}},
57	// Note that we can parse an email by itself without brackets, but can't support a comment in that case
58	{"mixture2", []string{"Patrick Crosby (test comment1)", "(test comment3) <ab@ab.com>", "CD (test comment4) <cd@cd.com>"}, nil, []Identity{
59		{Username: "Patrick Crosby", Comment: "test comment1"},
60		{Email: "ab@ab.com", Comment: "test comment3"},
61		{Username: "CD", Comment: "test comment4", Email: "cd@cd.com"},
62	}},
63}
64
65func TestCreateIds(t *testing.T) {
66	tc := SetupTest(t, "createIds", 1)
67	defer tc.Cleanup()
68
69	// We need to fake the call to G.Env.GetUsername().  The best way to do this is to
70	// fake an entire UserConfig. Most of these fields won't be used in this test, so it's
71	// ok to give empty UIDs/Salts.
72	uid, _ := keybase1.UIDFromString("00000000000000000000000000000019")
73	var nilDeviceID keybase1.DeviceID
74	err := tc.G.Env.GetConfigWriter().SetUserConfig(NewUserConfig(uid, "foo", []byte{}, nilDeviceID), true)
75	if err != nil {
76		t.Errorf("Set user config err: %+v", err)
77	}
78
79	for _, test := range cidTests {
80		arg := &PGPGenArg{PrimaryBits: 1024, SubkeyBits: 1024, PGPUids: test.pgpUIDArg}
81		if err := arg.Init(); err != nil {
82			t.Errorf("%s: arg init err: %s", test.name, err)
83			continue
84		}
85		err := arg.CreatePGPIDs()
86		if err != test.errOut {
87			t.Errorf("%s: error %v, expected %v", test.name, err, test.errOut)
88			continue
89		}
90		if test.errOut != nil {
91			// this is an error test, no need to do anything else
92			continue
93		}
94		if len(arg.Ids) != len(test.idsOut) {
95			t.Errorf("%s: %d IDs, expected %d.", test.name, len(arg.Ids), len(test.idsOut))
96			continue
97		}
98		for i, id := range arg.Ids {
99			if id != test.idsOut[i] {
100				t.Errorf("%s: id %d = %+v, expected %+v", test.name, i, id, test.idsOut[i])
101			}
102		}
103
104		if len(arg.Ids) == 0 {
105			continue
106		}
107
108		// test the PGPKeyBundle
109		bundle, err := GeneratePGPKeyBundle(tc.G, *arg, tc.G.UI.GetLogUI())
110		if err != nil {
111			t.Errorf("%s: bundle error: %s", test.name, err)
112		}
113		if len(bundle.Identities) != len(test.idsOut) {
114			t.Errorf("%s: %d bundle ids, expected %d", test.name, len(bundle.Identities), len(test.idsOut))
115			continue
116		}
117		pids, err := arg.PGPUserIDs()
118		if err != nil {
119			t.Errorf("%s: pgp user id conversion error: %q", test.name, err)
120			continue
121		}
122		for _, id := range pids {
123			bundleID, ok := bundle.Identities[id.Id]
124			if !ok {
125				t.Errorf("%s: no bundle identity found for %q", test.name, id.Id)
126				continue
127			}
128			if *(bundleID.UserId) != *id {
129				t.Errorf("%s: bundle UserId = %+v, expected %+v", test.name, bundleID.UserId, id)
130				continue
131			}
132		}
133	}
134}
135