@@ -6,9 +6,12 @@ import (
66 "compress/gzip"
77 "context"
88 "errors"
9+ "fmt"
910 "io"
1011 "net/http"
1112 "testing"
13+
14+ "github.com/reMarkable/orbit/pkg/mcache"
1215)
1316
1417type mockHTTPClient struct {
@@ -40,7 +43,7 @@ func TestService_ListVersions(t *testing.T) {
4043 cfg := Config {
4144 OrgMappings : map [string ]string {"test-system" : "test-org" },
4245 }
43- service := New (cfg , mockClient )
46+ service := New (cfg , mockClient , mcache. New [ string , [] string ]( mcache . NoExpiration ) )
4447
4548 versions , err := service .ListVersions (context .Background (), "test-system" , "test-repo" , "module" )
4649 if err != nil {
@@ -97,7 +100,7 @@ func TestService_ProxyDownload(t *testing.T) {
97100 cfg := Config {
98101 OrgMappings : map [string ]string {"test-system" : "test-org" },
99102 }
100- service := New (cfg , mockClient )
103+ service := New (cfg , mockClient , mcache. New [ string , [] string ]( mcache . NoExpiration ) )
101104
102105 var buf bytes.Buffer
103106 err := service .ProxyDownload (context .Background (), "test-system" , "test-repo" , "module" , "v1.0.0" , & buf )
@@ -126,3 +129,98 @@ func TestService_ProxyDownload(t *testing.T) {
126129 t .Errorf ("expected tarball to contain %q, but it was %q" , expectedContent , tarBuf .Bytes ())
127130 }
128131}
132+
133+ func TestService_ListVersions_CachesTagsPerRepo (t * testing.T ) {
134+ var calls int
135+ mockClient := & mockHTTPClient {
136+ doFunc : func (req * http.Request ) (* http.Response , error ) {
137+ if req .URL .Path == "/repos/test-org/test-repo/tags" {
138+ calls ++
139+ body := `[
140+ {"name": "module/v1.0.0"},
141+ {"name": "other/v2.0.0"}
142+ ]`
143+ return & http.Response {
144+ StatusCode : http .StatusOK ,
145+ Body : io .NopCloser (bytes .NewReader ([]byte (body ))),
146+ }, nil
147+ }
148+ return nil , errors .New ("unexpected request" )
149+ },
150+ }
151+
152+ cfg := Config {
153+ OrgMappings : map [string ]string {"test-system" : "test-org" },
154+ }
155+ service := New (cfg , mockClient , mcache.New [string , []string ](mcache .NoExpiration ))
156+
157+ // First call for "module" should hit the API.
158+ if _ , err := service .ListVersions (context .Background (), "test-system" , "test-repo" , "module" ); err != nil {
159+ t .Fatalf ("unexpected error: %v" , err )
160+ }
161+
162+ // Second call for a different module in the same repo should be served from
163+ // the cache without hitting the API again.
164+ other , err := service .ListVersions (context .Background (), "test-system" , "test-repo" , "other" )
165+ if err != nil {
166+ t .Fatalf ("unexpected error: %v" , err )
167+ }
168+
169+ if calls != 1 {
170+ t .Fatalf ("expected tags endpoint to be called once, got %d" , calls )
171+ }
172+
173+ if len (other ) != 1 || other [0 ] != "v2.0.0" {
174+ t .Errorf ("expected cached tags to yield [v2.0.0], got %v" , other )
175+ }
176+ }
177+
178+ func TestService_ListVersions_Pagination (t * testing.T ) {
179+ // Build a first page with exactly tagsPerPage entries to force a second request.
180+ var firstPage bytes.Buffer
181+ firstPage .WriteString ("[" )
182+ for i := 0 ; i < tagsPerPage ; i ++ {
183+ if i > 0 {
184+ firstPage .WriteString ("," )
185+ }
186+ fmt .Fprintf (& firstPage , `{"name": "filler/v0.0.%d"}` , i )
187+ }
188+ firstPage .WriteString ("]" )
189+
190+ mockClient := & mockHTTPClient {
191+ doFunc : func (req * http.Request ) (* http.Response , error ) {
192+ if req .URL .Path != "/repos/test-org/test-repo/tags" {
193+ return nil , errors .New ("unexpected request" )
194+ }
195+ switch req .URL .Query ().Get ("page" ) {
196+ case "1" :
197+ return & http.Response {
198+ StatusCode : http .StatusOK ,
199+ Body : io .NopCloser (bytes .NewReader (firstPage .Bytes ())),
200+ }, nil
201+ case "2" :
202+ body := `[{"name": "module/v1.0.0"}]`
203+ return & http.Response {
204+ StatusCode : http .StatusOK ,
205+ Body : io .NopCloser (bytes .NewReader ([]byte (body ))),
206+ }, nil
207+ default :
208+ return nil , errors .New ("unexpected page" )
209+ }
210+ },
211+ }
212+
213+ cfg := Config {
214+ OrgMappings : map [string ]string {"test-system" : "test-org" },
215+ }
216+ service := New (cfg , mockClient , mcache.New [string , []string ](mcache .NoExpiration ))
217+
218+ versions , err := service .ListVersions (context .Background (), "test-system" , "test-repo" , "module" )
219+ if err != nil {
220+ t .Fatalf ("unexpected error: %v" , err )
221+ }
222+
223+ if len (versions ) != 1 || versions [0 ] != "v1.0.0" {
224+ t .Errorf ("expected [v1.0.0] across pages, got %v" , versions )
225+ }
226+ }
0 commit comments