приём и чтение записей сведены к одному контракту приложения
- адреса приложения переехали в своё пространство `/app/`, опрос готовности убран целиком: рубеж и причину остановки владелец узнаёт карточкой записи, текст — отдельным адресом названного вида - заведена единая точка отображения доменной ошибки и слой, приводящий к той же форме отказы библиотеки: тело несёт машиночитаемый код рядом с сообщением - у записи появились имя файла отправителя, длительность и размер своими колонками, а у ленты владельца — свой индекс: без него страница сканировала весь архив сервиса
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// Имя файла приходит извне и содержимым своим приёму не подконтрольно. Правило
|
||||
// чистки живёт в домене, а не в транспорте: имя доходит до колонки записи одним
|
||||
// путём, и правил обязано быть одно.
|
||||
func TestSanitizeOriginalFilename(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
in string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "обычное имя не трогается",
|
||||
in: "разговор.mp3",
|
||||
want: "разговор.mp3",
|
||||
},
|
||||
{
|
||||
name: "управляющие знаки убираются",
|
||||
in: "разго\x00вор\x07\x1b.mp3",
|
||||
want: "разговор.mp3",
|
||||
},
|
||||
{
|
||||
name: "перевод строки — тоже управляющий знак",
|
||||
in: "первая\nвторая.mp3",
|
||||
want: "перваявторая.mp3",
|
||||
},
|
||||
{
|
||||
name: "пустое остаётся пустым",
|
||||
in: "",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert.Equal(t, tc.want, SanitizeOriginalFilename(tc.in))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Режется имя по знакам, а не по байтам: имя русское чаще, чем латинское, и
|
||||
// обрезка по байтам разрубила бы знак пополам.
|
||||
func TestSanitizeOriginalFilenameTrimsByRunes(t *testing.T) {
|
||||
long := strings.Repeat("я", MaxOriginalFilenameLen+50)
|
||||
|
||||
got := SanitizeOriginalFilename(long)
|
||||
|
||||
assert.Len(t, []rune(got), MaxOriginalFilenameLen, "длина считается знаками")
|
||||
assert.True(t, strings.HasPrefix(long, got), "обрезано с хвоста, а не переписано")
|
||||
assert.Equal(t, long[:len(got)], got, "ни один знак не разрублен пополам")
|
||||
}
|
||||
|
||||
// Уборка идёт до резки: иначе потолок съедали бы знаки, которых в сохранённом
|
||||
// имени всё равно не будет.
|
||||
func TestSanitizeOriginalFilenameCleansBeforeTrimming(t *testing.T) {
|
||||
dirty := strings.Repeat("\x00", 100) + strings.Repeat("я", MaxOriginalFilenameLen)
|
||||
|
||||
got := SanitizeOriginalFilename(dirty)
|
||||
|
||||
assert.Len(t, []rune(got), MaxOriginalFilenameLen,
|
||||
"сто управляющих знаков не откусили сто знаков имени")
|
||||
}
|
||||
Reference in New Issue
Block a user