oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1package docs_test
2
3import (
4 "bytes"
5 "crypto/sha256"
6 "encoding/base64"
7 "encoding/json"
8 "net/http"
9 "net/http/httptest"
10 "os"
11 "testing"
12 "time"
13
14 "github.com/carlosframework/docs/internal/docs"
15)
16
17// This optional fixture exists only in the test binary. The production app
18// never reads review credentials, bypasses origin checks, or seeds sample data.
19func TestNativeReviewFixture(t *testing.T) {
20 input, stop := os.Getenv("DOCS_NATIVE_REVIEW_INPUT"), os.Getenv("DOCS_NATIVE_REVIEW_STOP")
21 if input == "" || stop == "" {
22 t.Skip("interactive native review fixture not requested")
23 }
24 app := members(t, "native-review@example.test")
25 browser := signInCookies(t, app, "native-review@example.test")
26 sqid := createDoc(t, app, browser, "Native review document")
27 createDoc(t, app, browser, "Second review document")
28 owner := app.TestPerson(t, "native-review@example.test")
29 doc, err := app.Store().Get(t.Context(), owner, sqid)
30 if err != nil {
31 t.Fatal(err)
32 }
33 update, err := os.ReadFile("../../fixtures/vectors/fragment/formatted.update.bin")
34 if err != nil {
35 t.Fatal(err)
36 }
37 if _, err := app.Store().ApplyUpdate(t.Context(), doc, app.TestActorFor(t, doc), update); err != nil {
38 t.Fatal(err)
39 }
40 verifier := base64.RawURLEncoding.EncodeToString(bytes.Repeat([]byte{17}, 32))
41 hash := sha256.Sum256([]byte(verifier))
42 begin := nativeRequest(app, nil, "POST", "/native/request", `{"challenge":"`+base64.RawURLEncoding.EncodeToString(hash[:])+`"}`)
43 var pending struct{ ID string }
44 if begin.Code != 200 || json.Unmarshal(begin.Body.Bytes(), &pending) != nil {
45 t.Fatal("review native request failed")
46 }
47 if approval := nativeRequest(app, browser, "POST", "/native/authorize?id="+pending.ID, ""); approval.Code != 200 {
48 t.Fatal("review native approval failed")
49 }
50 exchanged := nativeRequest(app, nil, "POST", "/native/exchange", `{"id":"`+pending.ID+`","verifier":"`+verifier+`"}`)
51 var credential map[string]string
52 if exchanged.Code != 200 || json.Unmarshal(exchanged.Body.Bytes(), &credential) != nil || credential["value"] == "" {
53 t.Fatal("review native exchange failed")
54 }
55 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
56 // The ephemeral listener and canonical test origin differ. Only this
57 // isolated fixture adapts the Origin header; normal routes stay guarded.
58 r.Header.Set("Origin", docs.DefaultOrigin)
59 r.Header.Del("Sec-Fetch-Site")
60 app.Handler().ServeHTTP(w, r)
61 }))
62 defer server.Close()
63 defer server.CloseClientConnections()
64 data, err := json.Marshal(map[string]any{"origin": server.URL, "credential": credential, "sqid": sqid})
65 if err != nil {
66 t.Fatal(err)
67 }
68 file, err := os.OpenFile(input, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600)
69 if err != nil {
70 t.Fatal(err)
71 }
72 defer os.Remove(input)
73 if _, err := file.Write(data); err != nil {
74 file.Close()
75 t.Fatal(err)
76 }
77 if err := file.Close(); err != nil {
78 t.Fatal(err)
79 }
80 t.Log("Isolated native Docs review fixture ready")
81 deadline := time.NewTimer(10 * time.Minute)
82 defer deadline.Stop()
83 tick := time.NewTicker(200 * time.Millisecond)
84 defer tick.Stop()
85 for {
86 select {
87 case <-t.Context().Done():
88 return
89 case <-deadline.C:
90 t.Fatal("native review fixture timed out")
91 case <-tick.C:
92 if _, err := os.Stat(stop); err == nil {
93 return
94 }
95 }
96 }
97}
98