- адреса приложения переехали в своё пространство `/app/`, опрос готовности убран целиком: рубеж и причину остановки владелец узнаёт карточкой записи, текст — отдельным адресом названного вида - заведена единая точка отображения доменной ошибки и слой, приводящий к той же форме отказы библиотеки: тело несёт машиночитаемый код рядом с сообщением - у записи появились имя файла отправителя, длительность и размер своими колонками, а у ленты владельца — свой индекс: без него страница сканировала весь архив сервиса
70 lines
2.4 KiB
Go
70 lines
2.4 KiB
Go
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,
|
|
"сто управляющих знаков не откусили сто знаков имени")
|
|
}
|