@@ -14,7 +14,10 @@ import (
1414 "go-micro.dev/v4/client"
1515
1616 "github.com/opencloud-eu/opencloud/pkg/log"
17+ "github.com/opencloud-eu/opencloud/pkg/shared"
18+ searchmsg "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/messages/search/v0"
1719 searchsvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/search/v0"
20+ "github.com/opencloud-eu/opencloud/services/graph/pkg/config"
1821)
1922
2023type stubSearchService struct {
@@ -25,20 +28,25 @@ func (s stubSearchService) Search(_ context.Context, req *searchsvc.SearchReques
2528 return s .search (req )
2629}
2730
28- func (s stubSearchService ) IndexSpace (_ context.Context , _ * searchsvc.IndexSpaceRequest , _ ... client.CallOption ) (* searchsvc.IndexSpaceResponse , error ) {
31+ func (s stubSearchService ) IndexSpace (_ context.Context , _ * searchsvc.IndexSpaceRequest , _ ... client.CallOption ) (searchsvc.SearchProvider_IndexSpaceService , error ) {
2932 return nil , nil
3033}
3134
3235func graphWithSearch (stub stubSearchService ) Graph {
3336 logger := log .NewLogger ()
37+ cfg := & config.Config {Commons : & shared.Commons {OpenCloudURL : "https://cloud.example" }}
3438 return Graph {
35- BaseGraphService : BaseGraphService {logger : & logger },
39+ BaseGraphService : BaseGraphService {logger : & logger , config : cfg },
3640 searchService : stub ,
3741 }
3842}
3943
4044func postSearchQuery (g Graph , body string ) * httptest.ResponseRecorder {
41- req := httptest .NewRequest (http .MethodPost , "/search/query" , bytes .NewBufferString (body ))
45+ return postSearchQueryTarget (g , "/search/query" , body )
46+ }
47+
48+ func postSearchQueryTarget (g Graph , target , body string ) * httptest.ResponseRecorder {
49+ req := httptest .NewRequest (http .MethodPost , target , bytes .NewBufferString (body ))
4250 req .Header .Set ("Content-Type" , "application/json" )
4351 rr := httptest .NewRecorder ()
4452 g .SearchQuery (rr , req )
@@ -164,4 +172,83 @@ var _ = ginkgo.Describe("SearchQuery", func() {
164172 Expect (rr .Code ).To (Equal (http .StatusOK ), rr .Body .String ())
165173 Expect (called ).To (BeTrue ())
166174 })
175+
176+ ginkgo .It ("expands thumbnails on hits when $expand=thumbnails is requested" , func () {
177+ coverW , coverH := int32 (500 ), int32 (500 )
178+ g := graphWithSearch (stubSearchService {
179+ search : func (* searchsvc.SearchRequest ) (* searchsvc.SearchResponse , error ) {
180+ return & searchsvc.SearchResponse {
181+ TotalMatches : 3 ,
182+ Matches : []* searchmsg.Match {
183+ {Entity : & searchmsg.Entity {
184+ Id : & searchmsg.ResourceID {StorageId : "s" , SpaceId : "sp" , OpaqueId : "audio-with-cover" },
185+ Name : "song.flac" ,
186+ MimeType : "audio/flac" ,
187+ Preview : & searchmsg.Preview {Width : & coverW , Height : & coverH },
188+ }},
189+ {Entity : & searchmsg.Entity {
190+ Id : & searchmsg.ResourceID {StorageId : "s" , SpaceId : "sp" , OpaqueId : "audio-plain" },
191+ Name : "plain.flac" ,
192+ MimeType : "audio/flac" ,
193+ }},
194+ {Entity : & searchmsg.Entity {
195+ Id : & searchmsg.ResourceID {StorageId : "s" , SpaceId : "sp" , OpaqueId : "image" },
196+ Name : "pic.png" ,
197+ MimeType : "image/png" ,
198+ Image : & searchmsg.Image {Width : int32Ptr (1024 ), Height : int32Ptr (768 )},
199+ }},
200+ },
201+ }, nil
202+ },
203+ })
204+
205+ body := `{"requests": [{"entityTypes": ["driveItem"], "query": {"queryString": "*"}}]}`
206+
207+ rr := postSearchQueryTarget (g , "/search/query?$expand=thumbnails" , body )
208+ Expect (rr .Code ).To (Equal (http .StatusOK ), rr .Body .String ())
209+
210+ var resp struct {
211+ Value []struct {
212+ HitsContainers []struct {
213+ Hits []struct {
214+ Resource struct {
215+ Name string `json:"name"`
216+ Thumbnails []struct {
217+ Small * struct { Url string } `json:"small"`
218+ Source * struct {
219+ Url string
220+ Width , Height int32
221+ } `json:"source"`
222+ } `json:"thumbnails"`
223+ } `json:"resource"`
224+ } `json:"hits"`
225+ } `json:"hitsContainers"`
226+ } `json:"value"`
227+ }
228+ Expect (json .Unmarshal (rr .Body .Bytes (), & resp )).To (Succeed ())
229+ hits := resp .Value [0 ].HitsContainers [0 ].Hits
230+ Expect (hits ).To (HaveLen (3 ))
231+
232+ // audio with indexed cover art: thumbnails incl. exact-size source
233+ withCover := hits [0 ].Resource
234+ Expect (withCover .Thumbnails ).To (HaveLen (1 ))
235+ Expect (withCover .Thumbnails [0 ].Small .Url ).To (ContainSubstring ("https://cloud.example/dav/spaces/" ))
236+ Expect (withCover .Thumbnails [0 ].Source ).NotTo (BeNil ())
237+ Expect (withCover .Thumbnails [0 ].Source .Width ).To (Equal (int32 (500 )))
238+
239+ // audio without indexed cover art: no preview, no thumbnails
240+ Expect (hits [1 ].Resource .Thumbnails ).To (BeEmpty ())
241+
242+ // image: unconditional preview, source dimensions from the image facet
243+ image := hits [2 ].Resource
244+ Expect (image .Thumbnails ).To (HaveLen (1 ))
245+ Expect (image .Thumbnails [0 ].Source ).NotTo (BeNil ())
246+ Expect (image .Thumbnails [0 ].Source .Width ).To (Equal (int32 (1024 )))
247+ Expect (image .Thumbnails [0 ].Source .Height ).To (Equal (int32 (768 )))
248+
249+ // without $expand the hits stay bare
250+ rr = postSearchQueryTarget (g , "/search/query" , body )
251+ Expect (rr .Code ).To (Equal (http .StatusOK ), rr .Body .String ())
252+ Expect (rr .Body .String ()).NotTo (ContainSubstring ("thumbnails" ))
253+ })
167254})
0 commit comments