Live video on the AT Protocol
1package atproto
2
3import (
4 "context"
5 "encoding/base64"
6 "testing"
7
8 "github.com/bluesky-social/indigo/xrpc"
9)
10
11func TestKeyResolution(t *testing.T) {
12 // dir, err := os.MkdirTemp("", "atproto-test-*")
13 // require.NoError(t, err)
14 // defer os.RemoveAll(dir)
15
16 // fname := filepath.Join(dir, "db.sqlite")
17 // mod, err := model.MakeDB(fname)
18 // require.NoError(t, err)
19 // oldResolveIdent := ResolveIdent
20 // ResolveIdent = func(ctx context.Context, arg string) (*identity.Identity, error) {
21 // var doc identity.DIDDocument
22 // err = json.Unmarshal(didDoc, &doc)
23 // require.NoError(t, err)
24
25 // id := identity.ParseIdentity(&doc)
26 // return &id, nil
27 // }
28 // defer func() { ResolveIdent = oldResolveIdent }()
29 // oldSyncGetRepo := SyncGetRepo
30 // defer func() { SyncGetRepo = oldSyncGetRepo }()
31
32 // atsync := &ATProtoSynchronizer{
33 // Model: mod,
34 // }
35
36 // ctx := log.WithDebugValue(context.Background(), map[string]map[string]int{
37 // "func": {"handleCreateUpdate": 9, "SyncBlueskyRepo": 9},
38 // })
39
40 // // full sync
41 // SyncGetRepo = MockSyncGetRepo(fullSync)
42 // repo, err := atsync.SyncBlueskyRepo(ctx, "streamplace-test", mod)
43 // require.NoError(t, err)
44 // keys, err := mod.GetSigningKeysForRepo(repo.DID)
45 // require.NoError(t, err)
46 // require.Len(t, keys, 1)
47 // require.Equal(t, firstKey, keys[0].DID)
48
49 // // incremental sync with no changes
50 // SyncGetRepo = MockSyncGetRepo(incrementalSyncSameKey)
51 // repo, err = atsync.SyncBlueskyRepo(context.Background(), "streamplace-test", mod)
52 // require.NoError(t, err)
53 // keys, err = mod.GetSigningKeysForRepo(repo.DID)
54 // require.NoError(t, err)
55 // require.Len(t, keys, 1)
56 // require.Equal(t, firstKey, keys[0].DID)
57
58 // // incremental sync with a new streamplace key
59 // SyncGetRepo = MockSyncGetRepo(incrementalSyncNewKey)
60 // repo, err = atsync.SyncBlueskyRepo(context.Background(), "streamplace-test", mod)
61 // require.NoError(t, err)
62 // keys, err = mod.GetSigningKeysForRepo(repo.DID)
63 // require.NoError(t, err)
64 // require.Len(t, keys, 2)
65 // require.Equal(t, firstKey, keys[0].DID)
66 // require.Equal(t, secondKey, keys[1].DID)
67
68 // // empty sync
69 // SyncGetRepo = MockSyncGetRepo(emptySync)
70 // repo, err = atsync.SyncBlueskyRepo(context.Background(), "streamplace-test", mod)
71 // require.NoError(t, err)
72 // keys, err = mod.GetSigningKeysForRepo(repo.DID)
73 // require.NoError(t, err)
74 // require.Len(t, keys, 2)
75 // require.Equal(t, firstKey, keys[0].DID)
76 // require.Equal(t, secondKey, keys[1].DID)
77}
78
79func MockSyncGetRepo(res string) func(ctx context.Context, xrpcc *xrpc.Client, did string, rev string) ([]byte, error) {
80 return func(ctx context.Context, xrpcc *xrpc.Client, did string, rev string) ([]byte, error) {
81 decoded, err := base64.URLEncoding.DecodeString(res)
82 if err != nil {
83 return nil, err
84 }
85 return decoded, nil
86 }
87}
88
89// captured from plc.directory
90var didDoc = []byte(`
91 {
92 "@context": [
93 "https://www.w3.org/ns/did/v1",
94 "https://w3id.org/security/multikey/v1",
95 "https://w3id.org/security/suites/secp256k1-2019/v1"
96 ],
97 "alsoKnownAs": [
98 "at://streamplace-test.bsky.social"
99 ],
100 "id": "did:plc:ee3n2hs2wkgrkskrz6whzrfs",
101 "service": [
102 {
103 "id": "#atproto_pds",
104 "serviceEndpoint": "https://grisette.us-west.host.bsky.network",
105 "type": "AtprotoPersonalDataServer"
106 }
107 ],
108 "verificationMethod": [
109 {
110 "controller": "did:plc:ee3n2hs2wkgrkskrz6whzrfs",
111 "id": "did:plc:ee3n2hs2wkgrkskrz6whzrfs#atproto",
112 "publicKeyMultibase": "zQ3shYTpdwFJJppCFwncKrB1hSTsKE48s1kTQASKvgSNm3jTt",
113 "type": "Multikey"
114 }
115 ]
116 }
117`)
118var firstKey = "did:key:zQ3shkP7pgLBqp7PYQYnFRSCTBdKAGHWKKghF3GidVmEMUrct"
119var secondKey = "did:key:zQ3shUjidTbELwdHjeNyvx8iQ8adi4789Eaan9Lgc9AUh1Vzm"
120var fullSync = `OqJlcm9vdHOB2CpYJQABcRIgMDc7EDUmj3o8uSuYkHfG46c34xUOpb9gmVTu-M9CbNdndmVyc2lvbgGmAQFxEiCHwNkrZ3dGh8V43q6FFuRg5LlgE50hifxzDmAdATYc6aNlJHR5cGVwcGxhY2Uuc3RyZWFtLmtleWljcmVhdGVkQXR4GDIwMjUtMDEtMjZUMjE6MDc6MzkuMTYxWmpzaWduaW5nS2V5eDlkaWQ6a2V5OnpRM3Noa1A3cGdMQnFwN1BZUVluRlJTQ1RCZEtBR0hXS0tnaEYzR2lkVm1FTVVyY3T4AQFxEiBzaFlz2gS4XkDfdJHIjomgqdCpk7Cc49rX3kvYqLP6eaJhZYKkYWtYG2FwcC5ic2t5LmFjdG9yLnByb2ZpbGUvc2VsZmFwAGF02CpYJQABcRIgVDDzvM6e19so-zvPpJEldfpzAbpZZ6WxE81LAYvjCv1hdtgqWCUAAXESIMzJIP4DaRsw1NyMu1Su2ggAXMDz0nOK13rNPkQz00L0pGFrWB5wbGFjZS5zdHJlYW0ua2V5LzNsZ29kZ3Q2bzY1MjRhcABhdPZhdtgqWCUAAXESIIfA2Stnd0aHxXjeroUW5GDkuWATnSGJ_HMOYB0BNhzpYWz24AEBcRIgMDc7EDUmj3o8uSuYkHfG46c34xUOpb9gmVTu-M9CbNemY2RpZHggZGlkOnBsYzplZTNuMmhzMndrZ3Jrc2tyejZ3aHpyZnNjcmV2bTNsZ29kZ3Q2dHpuMjRjc2lnWEDo6aLAaagS8QCgO_fuXpYApipc9VpFI4mmOPpmIIKWyHQnXiMurYyqNs0oGX31lXUmBlNQq0mUDKY8D2FbxSyaZGRhdGHYKlglAAFxEiBzaFlz2gS4XkDfdJHIjomgqdCpk7Cc49rX3kvYqLP6eWRwcmV29md2ZXJzaW9uA84BAXESIMzJIP4DaRsw1NyMu1Su2ggAXMDz0nOK13rNPkQz00L0pGUkdHlwZXZhcHAuYnNreS5hY3Rvci5wcm9maWxlZmF2YXRhcqRjcmVm2CpYJQABVRIgHdCQPIz2IErjjii59bHG-XOJjtGVJLiR1RRnLKsXK3xkc2l6ZRl3ZmUkdHlwZWRibG9iaG1pbWVUeXBlaWltYWdlL3BuZ2ljcmVhdGVkQXR4GDIwMjUtMDEtMjZUMjE6MDQ6MzUuNjMxWmtkaXNwbGF5TmFtZWCEAQFxEiBUMPO8zp7X2yj7O8-kkSV1-nMBullnpbETzUsBi-MK_aJhZYGkYWtYI2FwcC5ic2t5LmdyYXBoLmZvbGxvdy8zbGdvZGJkM3poYzJoYXAAYXT2YXbYKlglAAFxEiAOO157S10FbyFkhacvqpz-lvrDDv1i9kTTw7p26_NFX2Fs9o8BAXESIA47XntLXQVvIWSFpy-qnP6W-sMO_WL2RNPDunbr80Vfo2UkdHlwZXVhcHAuYnNreS5ncmFwaC5mb2xsb3dnc3ViamVjdHggZGlkOnBsYzp6NzJpN2hkeW5tazZyMjJ6MjdoNnR2dXJpY3JlYXRlZEF0eBgyMDI1LTAxLTI2VDIxOjA0OjM0LjcxM1o=`
121var incrementalSyncSameKey = `OqJlcm9vdHOB2CpYJQABcRIgKRCUWJjPxaq1aqO7srwRxpJeURCsoQ_sXJaSkyscKXRndmVyc2lvbgHRAQFxEiD8HmkbON-0uUXvBD5PHbTu9hfJYYh7BcQBBbua6OlXNqJhZYKkYWtYIGFwcC5ic2t5LmZlZWQucG9zdC8zbGdvZGx3eGg0dDJoYXAAYXT2YXbYKlglAAFxEiAJRIEWBgnKqUlv19Ese8UO557t5YL7jfcEBItUpEm9IqRha1gaZ3JhcGguZm9sbG93LzNsZ29kYmQzemhjMmhhcAlhdPZhdtgqWCUAAXESIA47XntLXQVvIWSFpy-qnP6W-sMO_WL2RNPDunbr80VfYWz2-AEBcRIguxQZbYxqjerYzPJzsB2cq47_Cy-M9DbdfX3zgsZsHSKiYWWCpGFrWBthcHAuYnNreS5hY3Rvci5wcm9maWxlL3NlbGZhcABhdNgqWCUAAXESIPweaRs437S5Re8EPk8dtO72F8lhiHsFxAEFu5ro6Vc2YXbYKlglAAFxEiDMySD-A2kbMNTcjLtUrtoIAFzA89Jzitd6zT5EM9NC9KRha1gecGxhY2Uuc3RyZWFtLmtleS8zbGdvZGd0Nm82NTI0YXAAYXT2YXbYKlglAAFxEiCHwNkrZ3dGh8V43q6FFuRg5LlgE50hifxzDmAdATYc6WFs9uABAXESICkQlFiYz8WqtWqju7K8EcaSXlEQrKEP7FyWkpMrHCl0pmNkaWR4IGRpZDpwbGM6ZWUzbjJoczJ3a2dya3Nrcno2d2h6cmZzY3Jldm0zbGdvZGx3eXhkeDJqY3NpZ1hAokbAmjkgNdLlufRil-TeFuxKggit3Ljqkbw7QKRY794EPZYnb1WQE6sPhcF7Z0VNTl05APJPEb0s4SKM8qloRGRkYXRh2CpYJQABcRIguxQZbYxqjerYzPJzsB2cq47_Cy-M9DbdfX3zgsZsHSJkcHJldvZndmVyc2lvbgOIAQFxEiAJRIEWBgnKqUlv19Ese8UO557t5YL7jfcEBItUpEm9IqRkdGV4dHZIaSB0aGlzIGlzIGEgdGVzdCBwb3N0ZSR0eXBlcmFwcC5ic2t5LmZlZWQucG9zdGVsYW5nc4FiZW5pY3JlYXRlZEF0eBgyMDI1LTAxLTI2VDIxOjEwOjMxLjA4MFo=`
122var incrementalSyncNewKey = `OqJlcm9vdHOB2CpYJQABcRIglIEJIf3uyrHn7zpaDG0VZ5LFVpEnAO4COXPLdZVI5N5ndmVyc2lvbgGmAQFxEiC7UEFQdgwPLi4Aph-E0JNXfiJhpy7EK7yIae9mt-JLlqNlJHR5cGVwcGxhY2Uuc3RyZWFtLmtleWljcmVhdGVkQXR4GDIwMjUtMDEtMjZUMjE6MTA6NTkuMDI5WmpzaWduaW5nS2V5eDlkaWQ6a2V5OnpRM3NoVWppZFRiRUx3ZEhqZU55dng4aVE4YWRpNDc4OUVhYW45TGdjOUFVaDFWem3gAQFxEiCUgQkh_e7KsefvOloMbRVnksVWkScA7gI5c8t1lUjk3qZjZGlkeCBkaWQ6cGxjOmVlM24yaHMyd2tncmtza3J6NndoenJmc2NyZXZtM2xnb2RtcnJqb3EydGNzaWdYQPoUwYR8ZFqHPygnPU0Yzo14pRo35huNbjVwtQudrSIMErQMHsGhZL-JdLnq5avgxXYqq7k4jcMUEkUIgmZFI51kZGF0YdgqWCUAAXESIEBLuaWzxeuRKjP8Kovw6ZWkkvqfMkhDOBymBuE4ZZhRZHByZXb2Z3ZlcnNpb24DtQIBcRIgQEu5pbPF65EqM_wqi_DplaSS-p8ySEM4HKYG4ThlmFGiYWWDpGFrWBthcHAuYnNreS5hY3Rvci5wcm9maWxlL3NlbGZhcABhdNgqWCUAAXESIPweaRs437S5Re8EPk8dtO72F8lhiHsFxAEFu5ro6Vc2YXbYKlglAAFxEiDMySD-A2kbMNTcjLtUrtoIAFzA89Jzitd6zT5EM9NC9KRha1gecGxhY2Uuc3RyZWFtLmtleS8zbGdvZGd0Nm82NTI0YXAAYXT2YXbYKlglAAFxEiCHwNkrZ3dGh8V43q6FFuRg5LlgE50hifxzDmAdATYc6aRha0htcnJmcnEydGFwFmF09mF22CpYJQABcRIgu1BBUHYMDy4uAKYfhNCTV34iYacuxCu8iGnvZrfiS5ZhbPY=`
123var emptySync = `OqJlcm9vdHOB2CpYJQABcRIglIEJIf3uyrHn7zpaDG0VZ5LFVpEnAO4COXPLdZVI5N5ndmVyc2lvbgE=`