| 1 | package tinyclient |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "encoding/json" |
| 6 | "net/http" |
| 7 | "net/http/httptest" |
| 8 | "strings" |
| 9 | "testing" |
| 10 | |
| 11 | "github.com/FelineStateMachine/tinyrelay/internal/policy" |
| 12 | ) |
| 13 | |
| 14 | type fileLibraryBackend struct{ fakeBackend } |
| 15 | |
| 16 | func (b *fileLibraryBackend) Query(_ context.Context, method string, params []json.RawMessage, actor string) (any, error) { |
| 17 | if method != "browsefiles" { |
| 18 | return nil, nil |
| 19 | } |
| 20 | b.call, b.params = method+":" +actor, params |
| 21 | var query map[string]any |
| 22 | if err := json.Unmarshal(params[0], &query); err != nil { |
| 23 | return nil, err |
| 24 | } |
| 25 | return map[string]any{ |
| 26 | "view" : query["view" ], "path" : query["path" ], "can_manage" : true, "next_cursor" : "next-file" , |
| 27 | "breadcrumbs" : []map[string]string{{"name" : "My files" , "open" : "/files" }, {"name" : "Trip" , "open" : "/files?path=Trip" }}, |
| 28 | "items" : []map[string]any{ |
| 29 | {"kind" : "folder" , "name" : "Photos" , "path" : "Trip/Photos" , "open" : "/files?path=Trip%2FPhotos" }, |
| 30 | {"kind" : "file" , "name" : "Snow & sun.jpg" , "sha256" : strings.Repeat("f" , 64), "type" : "image/jpeg" , "size" : 16384, "uploaded" : 1789066800}, |
| 31 | }, |
| 32 | }, nil |
| 33 | } |
| 34 | |
| 35 | func TestFilesRenderNamedFoldersAndPreserveBrowseQuery(t *testing.T) { |
| 36 | backend := &fileLibraryBackend{fakeBackend{policy: policy.Defaults(strings.Repeat("a" , 64))}} |
| 37 | app, err := New(backend, Options{Actor: func(*http.Request) (string, error) { return backend.policy.Owner, nil }}) |
| 38 | if err != nil { |
| 39 | t.Fatal(err) |
| 40 | } |
| 41 | for _, target := range []string{"/files" , "/files?view=sites&path=Trip&q=snow&cursor=old" } { |
| 42 | response := httptest.NewRecorder() |
| 43 | app.ServeHTTP(response, httptest.NewRequest(http.MethodGet, target, nil)) |
| 44 | if response.Code != http.StatusOK { |
| 45 | t.Fatalf("%s: status %d" , target, response.Code) |
| 46 | } |
| 47 | var query map[string]any |
| 48 | if err := json.Unmarshal(backend.params[0], &query); err != nil { |
| 49 | t.Fatal(err) |
| 50 | } |
| 51 | body := response.Body.String() |
| 52 | for _, want := range []string{`id="file-library"` , `aria-label="File collections"` , `Snow & sun.jpg` , `Photos` , `16.0 KiB` , `loading="lazy"` , `next-file` } { |
| 53 | if !strings.Contains(body, want) { |
| 54 | t.Errorf("%s missing %q" , target, want) |
| 55 | } |
| 56 | } |
| 57 | if target == "/files" { |
| 58 | if query["view" ] != "library" || !strings.Contains(body, `href="/files" aria-current="page"` ) { |
| 59 | t.Fatalf("default view was not library: %#v" , query) |
| 60 | } |
| 61 | } else if query["view" ] != "sites" || query["path" ] != "Trip" || query["q" ] != "snow" || query["cursor" ] != "old" || !strings.Contains(body, `path=Trip` ) || !strings.Contains(body, `q=snow` ) { |
| 62 | t.Fatalf("browse query was lost: %#v" , query) |
| 63 | } |
| 64 | } |
| 65 | } |