приложение собрано каркасом и вшито в бинарник
- заведён каталог web/ — Vue 3, роутер пятой версии, сборка Vite; собранное вшивается через go:embed и раздаётся корневым маршрутом: разметка на неизвестном пути вне корней сервиса, отказ контракта внутри корня - перечень корней сервиса стал единой точкой и порождает регистрацию маршрутов, а не описывает её; журнал раздачи пишет исход и длину пути, но не сам путь - шаг front зовёт Node контейнером docker — Biome, юнит-тесты Vue и сборка входят в гейт, а в Dockerfile появилась ступень приложения
This commit is contained in:
+34
-2
@@ -1,11 +1,27 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
httpcontroller "git.vakhrushev.me/av/transcriber/internal/controller/http"
|
||||
)
|
||||
|
||||
// Перечень адресного пространства для проверок журнала. Обработчиков он здесь
|
||||
// не вешает: журналу нужны только границы, а не то, что стоит за ними.
|
||||
func journalMounts() []httpcontroller.Mount {
|
||||
return []httpcontroller.Mount{
|
||||
{Path: httpcontroller.StorageRoot},
|
||||
{Path: httpcontroller.PanelRoot},
|
||||
{Path: httpcontroller.AppRoot},
|
||||
{Path: httpcontroller.AuthRoot},
|
||||
{Path: httpcontroller.HealthPath, Exact: true},
|
||||
{Path: httpcontroller.MetricsPath, Exact: true},
|
||||
}
|
||||
}
|
||||
|
||||
// Имя файла в хранилище в журнал не идёт: оно последняя часть ссылки
|
||||
// `/api/files/...`, и строка журнала вместе с идентификатором записи собрала бы
|
||||
// ссылку целиком. Инвариант проекта, critical.
|
||||
@@ -44,7 +60,7 @@ func TestJournalRouteHidesStoredFileName(t *testing.T) {
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
assert.Equal(t, c.want, journalRoute(c.path))
|
||||
assert.Equal(t, c.want, journalRoute(c.path, journalMounts()))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -54,8 +70,24 @@ func TestJournalRouteHidesStoredFileName(t *testing.T) {
|
||||
func TestJournalRouteDropsNameEntirely(t *testing.T) {
|
||||
const stored = "0f7b8dd3-d1cc-424c.mp3"
|
||||
|
||||
route := journalRoute("/api/files/files/rec0000000000000/" + stored)
|
||||
route := journalRoute("/api/files/files/rec0000000000000/"+stored, journalMounts())
|
||||
|
||||
assert.NotContains(t, route, stored, "имя файла в хранилище не доезжает до журнала")
|
||||
assert.Contains(t, route, "rec0000000000000", "идентификатор записи остаётся: по нему прослеживается путь")
|
||||
}
|
||||
|
||||
// Путь, не принадлежащий сервису, уходит приложению и в журнал дословно не
|
||||
// идёт: множеством его значений распоряжается спрашивающий.
|
||||
func TestJournalRouteHidesWebappPath(t *testing.T) {
|
||||
cases := []string{
|
||||
"/",
|
||||
"/records/abc123def456ghi",
|
||||
"/" + strings.Repeat("a", 1024),
|
||||
}
|
||||
|
||||
for _, path := range cases {
|
||||
route := journalRoute(path, journalMounts())
|
||||
|
||||
assert.Equal(t, webappRoute, route)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user