generated from VLADIMIR/template
clear
This commit is contained in:
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"evening_detective_server/internal/modules/file_storage"
|
||||
"evening_detective_server/internal/modules/processor_jwt"
|
||||
"evening_detective_server/internal/modules/string_tools"
|
||||
"evening_detective_server/internal/services/file_service"
|
||||
proto "evening_detective_server/proto"
|
||||
|
||||
@@ -63,7 +62,7 @@ func newTestFileServer(storage *fakeStorage, maxSize int) *server {
|
||||
storage = newFakeStorage()
|
||||
}
|
||||
return &server{
|
||||
fileService: file_service.NewFileService(storage, string_tools.NewStringTools(), maxSize),
|
||||
fileService: file_service.NewFileService(storage, maxSize),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"evening_detective_server/internal/modules/processor_jwt"
|
||||
"evening_detective_server/internal/modules/roles"
|
||||
"evening_detective_server/internal/modules/scenario_archive"
|
||||
"evening_detective_server/internal/modules/string_tools"
|
||||
"evening_detective_server/internal/repos/scenarios_repo"
|
||||
"evening_detective_server/internal/services/scenarios_service"
|
||||
proto "evening_detective_server/proto"
|
||||
@@ -45,7 +46,7 @@ func (s *server) DownloadScenarioArchive(ctx context.Context, req *proto.Downloa
|
||||
|
||||
// Имя файла транслитерируется (заголовки HTTP — только ASCII) и
|
||||
// санитайзится от header injection; заголовок пробрасывается gateway.
|
||||
transliterated := sanitizeFilename(stringTools.Transliterate(name))
|
||||
transliterated := sanitizeFilename(string_tools.Transliterate(name))
|
||||
if transliterated == "" {
|
||||
transliterated = "scenario"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"evening_detective_server/internal/modules/string_tools"
|
||||
"evening_detective_server/internal/repos/game_map_repo"
|
||||
"evening_detective_server/internal/repos/screen_sessions_repo"
|
||||
"evening_detective_server/internal/services/answer_service"
|
||||
@@ -16,9 +15,6 @@ import (
|
||||
proto "evening_detective_server/proto"
|
||||
)
|
||||
|
||||
// stringTools — транслитерация имён файлов для HTTP-заголовков.
|
||||
var stringTools = string_tools.NewStringTools()
|
||||
|
||||
type server struct {
|
||||
proto.UnsafeEveningDetectiveServerServer
|
||||
|
||||
|
||||
@@ -9,9 +9,6 @@ import (
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
// textFormatter — форматирование текста при конвертации входящих данных.
|
||||
var textFormatter = formatter_utils.NewFormatter()
|
||||
|
||||
func mapScenarios(o []*scenarios_service.Scenario) []*proto.Scenario {
|
||||
res := make([]*proto.Scenario, 0, len(o))
|
||||
for _, item := range o {
|
||||
@@ -66,7 +63,7 @@ func convertConclusion(o *proto.Conclusion) *storytelling.Conclusion {
|
||||
if o == nil || (o.Text == "" && o.Video == "") {
|
||||
return nil
|
||||
}
|
||||
return &storytelling.Conclusion{Text: textFormatter.FormatText(o.Text), Video: o.Video}
|
||||
return &storytelling.Conclusion{Text: formatter_utils.FormatText(o.Text), Video: o.Video}
|
||||
}
|
||||
|
||||
func mapIntroduction(o *storytelling.Introduction) *proto.Introduction {
|
||||
@@ -149,8 +146,8 @@ func mapKey(o *storytelling.Key) *proto.Key {
|
||||
func convertPlace(o *proto.Place) *storytelling.Place {
|
||||
return &storytelling.Place{
|
||||
Code: o.Code,
|
||||
Name: textFormatter.FormatString(o.Name),
|
||||
Text: textFormatter.FormatText(o.Text),
|
||||
Name: formatter_utils.FormatString(o.Name),
|
||||
Text: formatter_utils.FormatText(o.Text),
|
||||
Image: o.Image,
|
||||
Hidden: o.Hidden,
|
||||
Applications: convertApplications(o.Applications),
|
||||
@@ -185,7 +182,7 @@ func convertKeys(o []*proto.Key) []*storytelling.Key {
|
||||
|
||||
func convertApplication(o *proto.Application) *storytelling.Application {
|
||||
return &storytelling.Application{
|
||||
Name: textFormatter.FormatString(o.Name),
|
||||
Name: formatter_utils.FormatString(o.Name),
|
||||
Image: o.Image,
|
||||
FileType: o.FileType,
|
||||
}
|
||||
@@ -194,14 +191,14 @@ func convertApplication(o *proto.Application) *storytelling.Application {
|
||||
func convertDoor(o *proto.Door) *storytelling.Door {
|
||||
return &storytelling.Door{
|
||||
Code: o.Code,
|
||||
Name: textFormatter.FormatString(o.Name),
|
||||
Name: formatter_utils.FormatString(o.Name),
|
||||
Keys: convertKeys(o.Keys),
|
||||
}
|
||||
}
|
||||
|
||||
func convertKey(o *proto.Key) *storytelling.Key {
|
||||
return &storytelling.Key{
|
||||
Name: textFormatter.FormatString(o.Name),
|
||||
Name: formatter_utils.FormatString(o.Name),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +207,7 @@ func convertIntroduction(o *proto.Introduction) *storytelling.Introduction {
|
||||
return nil
|
||||
}
|
||||
return &storytelling.Introduction{
|
||||
Text: textFormatter.FormatText(o.Text),
|
||||
Text: formatter_utils.FormatText(o.Text),
|
||||
Audio: o.Audio,
|
||||
}
|
||||
}
|
||||
@@ -240,7 +237,7 @@ func convertQuestion(o *proto.Question) *storytelling.Question {
|
||||
}
|
||||
return &storytelling.Question{
|
||||
Code: o.Code,
|
||||
Text: textFormatter.FormatText(o.Text),
|
||||
Answer: textFormatter.FormatText(o.Answer),
|
||||
Text: formatter_utils.FormatText(o.Text),
|
||||
Answer: formatter_utils.FormatText(o.Answer),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package formatter_utils
|
||||
|
||||
// IFormatter — форматирование текста сценария для отображения.
|
||||
type IFormatter interface {
|
||||
FormatText(text string) string
|
||||
FormatString(text string) string
|
||||
}
|
||||
@@ -5,16 +5,9 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type formatter struct{}
|
||||
|
||||
// NewFormatter создаёт реализацию IFormatter.
|
||||
func NewFormatter() IFormatter {
|
||||
return &formatter{}
|
||||
}
|
||||
|
||||
// FormatText форматирует многострочный текст: обрезает пробелы по краям
|
||||
// строк, превращает "--" в тире и добавляет отступ абзаца.
|
||||
func (f *formatter) FormatText(text string) string {
|
||||
func FormatText(text string) string {
|
||||
scanner := bufio.NewScanner(strings.NewReader(text))
|
||||
|
||||
scanner.Split(bufio.ScanLines)
|
||||
@@ -46,7 +39,7 @@ func (f *formatter) FormatText(text string) string {
|
||||
|
||||
// FormatString форматирует одиночную строку: обрезает пробелы и заменяет
|
||||
// "--" на тире.
|
||||
func (f *formatter) FormatString(text string) string {
|
||||
func FormatString(text string) string {
|
||||
l := strings.TrimSpace(text)
|
||||
if strings.HasPrefix(l, "--") {
|
||||
l = strings.Replace(l, "--", "—", 1)
|
||||
|
||||
@@ -29,10 +29,9 @@ func Test_service_FormatText(t *testing.T) {
|
||||
want: " — Привет",
|
||||
},
|
||||
}
|
||||
formatter := NewFormatter()
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := formatter.FormatText(tt.text)
|
||||
got := FormatText(tt.text)
|
||||
if got != tt.want {
|
||||
t.Errorf("FormatText() = %v, want %v", got, tt.want)
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
package string_tools
|
||||
|
||||
// IStringTools — утилиты работы со строками.
|
||||
type IStringTools interface {
|
||||
// Transliterate выполняет транслитерацию русского текста в латиницу.
|
||||
Transliterate(text string) string
|
||||
}
|
||||
@@ -44,16 +44,9 @@ var (
|
||||
)
|
||||
)
|
||||
|
||||
type stringTools struct{}
|
||||
|
||||
// NewStringTools создаёт реализацию IStringTools.
|
||||
func NewStringTools() IStringTools {
|
||||
return &stringTools{}
|
||||
}
|
||||
|
||||
// Transliterate выполняет транслитерацию русского текста в латиницу,
|
||||
// заменяет пробелы на _, удаляет все остальные символы, кроме цифр (знаки препинания и т.д.)
|
||||
func (s *stringTools) Transliterate(text string) string {
|
||||
func Transliterate(text string) string {
|
||||
|
||||
// Приводим к нижнему регистру и транслитерируем
|
||||
result := replacer.Replace(strings.ToLower(text))
|
||||
|
||||
@@ -40,18 +40,15 @@ var allowedExtensions = map[string]struct{}{
|
||||
|
||||
type FileService struct {
|
||||
fileStorage file_storage.IFileStorage
|
||||
stringTools string_tools.IStringTools
|
||||
maxFileSize int
|
||||
}
|
||||
|
||||
func NewFileService(
|
||||
fileStorage file_storage.IFileStorage,
|
||||
stringTools string_tools.IStringTools,
|
||||
maxFileSize int,
|
||||
) *FileService {
|
||||
return &FileService{
|
||||
fileStorage: fileStorage,
|
||||
stringTools: stringTools,
|
||||
maxFileSize: maxFileSize,
|
||||
}
|
||||
}
|
||||
@@ -86,7 +83,7 @@ func (s *FileService) UploadFile(
|
||||
|
||||
// Транслитерация может обнулить base (например, «!!!.pdf»): хранимое
|
||||
// имя без base недопустимо — проверяем до размера и содержимого.
|
||||
transliterated := s.stringTools.Transliterate(base)
|
||||
transliterated := string_tools.Transliterate(base)
|
||||
if transliterated == "" {
|
||||
return "", "", ErrEmptyName
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"evening_detective_server/internal/modules/file_storage"
|
||||
"evening_detective_server/internal/modules/string_tools"
|
||||
)
|
||||
|
||||
// fakeStorage — in-memory реализация IFileStorage для тестов.
|
||||
@@ -44,7 +43,7 @@ func (s *fakeStorage) MimeType(filename string) string {
|
||||
}
|
||||
|
||||
func newService(maxFileSize int) *FileService {
|
||||
return NewFileService(newFakeStorage(), string_tools.NewStringTools(), maxFileSize)
|
||||
return NewFileService(newFakeStorage(), maxFileSize)
|
||||
}
|
||||
|
||||
func mustUpload(t *testing.T, svc *FileService, filename string, data []byte) (string, string) {
|
||||
|
||||
Reference in New Issue
Block a user