github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/chat/unfurl/packager_test.go (about) 1 package unfurl 2 3 import ( 4 "bytes" 5 "context" 6 "crypto/sha256" 7 "fmt" 8 "io" 9 "net/http" 10 "os" 11 "path/filepath" 12 "testing" 13 14 "github.com/keybase/client/go/chat/globals" 15 16 "github.com/keybase/client/go/chat/attachments" 17 "github.com/keybase/client/go/libkb" 18 "github.com/keybase/client/go/protocol/chat1" 19 "github.com/keybase/client/go/protocol/gregor1" 20 "github.com/keybase/clockwork" 21 "github.com/stretchr/testify/require" 22 ) 23 24 type ptsigner struct{} 25 26 func (p *ptsigner) Sign(payload []byte) ([]byte, error) { 27 s := sha256.Sum256(payload) 28 return s[:], nil 29 } 30 31 type paramsRemote struct { 32 chat1.RemoteInterface 33 } 34 35 func (p paramsRemote) GetS3Params(ctx context.Context, arg chat1.GetS3ParamsArg) (chat1.S3Params, error) { 36 return chat1.S3Params{ 37 Bucket: "packager-test", 38 ObjectKey: libkb.RandStringB64(3), 39 }, nil 40 } 41 42 func TestPackager(t *testing.T) { 43 tc := libkb.SetupTest(t, "packager", 1) 44 defer tc.Cleanup() 45 g := globals.NewContext(tc.G, &globals.ChatContext{}) 46 47 store := attachments.NewStoreTesting(g, nil) 48 s3Signer := &ptsigner{} 49 ri := func() chat1.RemoteInterface { return paramsRemote{} } 50 packager := NewPackager(g, store, s3Signer, ri) 51 clock := clockwork.NewFakeClock() 52 packager.cache.setClock(clock) 53 srvFile := func(w io.Writer, name string) { 54 file, err := os.Open(name) 55 require.NoError(t, err) 56 defer file.Close() 57 _, err = io.Copy(w, file) 58 require.NoError(t, err) 59 } 60 srv := newDummyHTTPSrv(t, func(w http.ResponseWriter, r *http.Request) { 61 w.WriteHeader(200) 62 if r.URL.Query().Get("typ") == "favicon" { 63 srvFile(w, filepath.Join("testcases", "nytimes.ico")) 64 return 65 } 66 srvFile(w, filepath.Join("testcases", "nytogimage.jpg")) 67 }) 68 addr := srv.Start() 69 defer srv.Stop() 70 71 uid := gregor1.UID([]byte{0}) 72 convID := chat1.ConversationID([]byte{0}) 73 imageURL := fmt.Sprintf("http://%s/?typ=image", addr) 74 faviconURL := fmt.Sprintf("http://%s/?typ=favicon", addr) 75 raw := chat1.NewUnfurlRawWithGeneric(chat1.UnfurlGenericRaw{ 76 Url: "https://example.com", 77 ImageUrl: &imageURL, 78 FaviconUrl: &faviconURL, 79 }) 80 res, err := packager.Package(context.TODO(), uid, convID, raw) 81 require.NoError(t, err) 82 typ, err := res.UnfurlType() 83 require.NoError(t, err) 84 require.Equal(t, chat1.UnfurlType_GENERIC, typ) 85 image := res.Generic().Image 86 require.NotNil(t, image) 87 favicon := res.Generic().Favicon 88 require.NotNil(t, favicon) 89 require.NotZero(t, image.Metadata.Image().Height) 90 require.NotZero(t, image.Metadata.Image().Width) 91 require.NotZero(t, favicon.Metadata.Image().Height) 92 require.NotZero(t, favicon.Metadata.Image().Width) 93 94 // test caching 95 cacheKey := packager.cacheKey(uid, convID, raw) 96 cachedRes, valid := packager.cache.get(cacheKey) 97 require.True(t, valid) 98 require.Equal(t, res, cachedRes.data.(chat1.Unfurl)) 99 100 clock.Advance(defaultCacheLifetime * 2) 101 cachedRes, valid = packager.cache.get(cacheKey) 102 require.False(t, valid) 103 104 compareSol := func(name string, resDat []byte) { 105 dat, err := os.ReadFile(filepath.Join("testcases", name)) 106 require.NoError(t, err) 107 require.True(t, bytes.Equal(dat, resDat)) 108 } 109 var buf bytes.Buffer 110 s3params, err := ri().GetS3Params(context.TODO(), chat1.GetS3ParamsArg{ 111 ConversationID: convID, 112 TempCreds: true, 113 }) 114 require.NoError(t, err) 115 require.NoError(t, store.DownloadAsset(context.TODO(), s3params, *image, &buf, s3Signer, nil)) 116 compareSol("nytogimage_sol.jpg", buf.Bytes()) 117 buf.Reset() 118 require.NoError(t, store.DownloadAsset(context.TODO(), s3params, *favicon, &buf, s3Signer, nil)) 119 compareSol("nytimes_sol.ico", buf.Bytes()) 120 }