check / check (push) Successful in 3m31s
Each database target on the webhook page links to /hook/ID/targets/TARGETID/download, which streams the target's archive as archive-WEBHOOK-TARGET-YYYYMMDDTHHMMSSZ.json.gz: the webhook, the target, exported_at, and archived_events, one object per row keyed by column, a body that is not valid UTF-8 in base64 with body_encoding. The export reads one row at a time on its own connection inside a read-only transaction: one snapshot, and no write lock. The handler holds the rename lock only while it reads the names and opens the file. A missing archive exports empty and is not created. Model: opus-5-5
70 lines
1.8 KiB
Go
70 lines
1.8 KiB
Go
package server_test
|
|
|
|
import (
|
|
"compress/gzip"
|
|
"encoding/json"
|
|
"net/http"
|
|
"regexp"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/gorm/clause"
|
|
"sneak.berlin/go/webhooker/internal/database"
|
|
)
|
|
|
|
// TestHook_DownloadArchive follows the Download link the webhook page
|
|
// shows for a database target, and only for it, and gets the archive
|
|
// as a gzipped JSON file. Signed out, the link leads to the login page.
|
|
func TestHook_DownloadArchive(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
env := newTestEnv(t)
|
|
|
|
userID, _ := env.seedUser(t, "archivist", "somepassword")
|
|
cookies := env.authCookies(t, userID, "archivist")
|
|
wh := env.seedWebhook(t, userID)
|
|
env.seedTarget(t, wh.ID)
|
|
|
|
archive := &database.Target{
|
|
WebhookID: wh.ID,
|
|
Name: "kept",
|
|
Type: database.TargetTypeDatabase,
|
|
Active: true,
|
|
}
|
|
require.NoError(t,
|
|
env.db.DB().Omit(clause.Associations).Create(archive).Error,
|
|
)
|
|
|
|
page := env.get("/hook/"+wh.ID, cookies)
|
|
require.Equal(t, http.StatusOK, page.Code)
|
|
|
|
links := regexp.MustCompile(
|
|
`href="(/hook/[^/"]+/targets/[^/"]+/download)"`,
|
|
).FindAllStringSubmatch(page.Body.String(), -1)
|
|
require.Len(t, links, 1, "only the database target has a Download")
|
|
|
|
link := links[0][1]
|
|
assert.Equal(t,
|
|
"/hook/"+wh.ID+"/targets/"+archive.ID+"/download", link,
|
|
)
|
|
|
|
w := env.get(link, cookies)
|
|
require.Equal(t, http.StatusOK, w.Code)
|
|
assert.Equal(t, "application/gzip", w.Header().Get("Content-Type"))
|
|
|
|
zr, err := gzip.NewReader(w.Body)
|
|
require.NoError(t, err)
|
|
|
|
var got map[string]json.RawMessage
|
|
|
|
require.NoError(t, json.NewDecoder(zr).Decode(&got))
|
|
assert.JSONEq(t,
|
|
`{"id":"`+wh.ID+`","name":"routed"}`, string(got["webhook"]),
|
|
)
|
|
|
|
w = env.get(link, nil)
|
|
assert.Equal(t, http.StatusSeeOther, w.Code)
|
|
assert.Contains(t, w.Header().Get("Location"), "/pages/login")
|
|
}
|