From 3a40c818ef9ac27d89154c282b5e6b1cc99cb4c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Eduardo=20Jer=C3=A9z=20Gir=C3=B3n?= Date: Fri, 19 Jul 2024 23:13:55 -0600 Subject: [PATCH] Add string utility functions for file handling --- .../get_content_type_from_file_name.go | 62 +++++++++++++++++++ .../get_content_type_from_file_name_test.go | 38 ++++++++++++ internal/util/strutil/remove_leading_slash.go | 10 +++ .../util/strutil/remove_leading_slash_test.go | 50 +++++++++++++++ 4 files changed, 160 insertions(+) create mode 100644 internal/util/strutil/get_content_type_from_file_name.go create mode 100644 internal/util/strutil/get_content_type_from_file_name_test.go create mode 100644 internal/util/strutil/remove_leading_slash.go create mode 100644 internal/util/strutil/remove_leading_slash_test.go diff --git a/internal/util/strutil/get_content_type_from_file_name.go b/internal/util/strutil/get_content_type_from_file_name.go new file mode 100644 index 0000000..197e1f0 --- /dev/null +++ b/internal/util/strutil/get_content_type_from_file_name.go @@ -0,0 +1,62 @@ +package strutil + +import "strings" + +// GetContentTypeFromFileName returns the content type +// of a file based on its file extension from the name. +// +// If the file extension is not recognized, it returns +// "application/octet-stream". +func GetContentTypeFromFileName(fileName string) string { + fileName = strings.ToLower(fileName) + + if strings.HasSuffix(fileName, ".pdf") { + return "application/pdf" + } + + if strings.HasSuffix(fileName, ".png") { + return "image/png" + } + + if strings.HasSuffix(fileName, ".jpg") || strings.HasSuffix(fileName, ".jpeg") { + return "image/jpeg" + } + + if strings.HasSuffix(fileName, ".gif") { + return "image/gif" + } + + if strings.HasSuffix(fileName, ".bmp") { + return "image/bmp" + } + + if strings.HasSuffix(fileName, ".json") { + return "application/json" + } + + if strings.HasSuffix(fileName, ".csv") { + return "text/csv" + } + + if strings.HasSuffix(fileName, ".xml") { + return "application/xml" + } + + if strings.HasSuffix(fileName, ".txt") { + return "text/plain" + } + + if strings.HasSuffix(fileName, ".html") { + return "text/html" + } + + if strings.HasSuffix(fileName, ".zip") { + return "application/zip" + } + + if strings.HasSuffix(fileName, ".sql") { + return "application/sql" + } + + return "application/octet-stream" +} diff --git a/internal/util/strutil/get_content_type_from_file_name_test.go b/internal/util/strutil/get_content_type_from_file_name_test.go new file mode 100644 index 0000000..85d1ac1 --- /dev/null +++ b/internal/util/strutil/get_content_type_from_file_name_test.go @@ -0,0 +1,38 @@ +package strutil + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestGetContentTypeFromFileName(t *testing.T) { + tests := []struct { + fileName string + expected string + }{ + {"documento.pdf", "application/pdf"}, + {"imagen.png", "image/png"}, + {"foto.jpg", "image/jpeg"}, + {"foto.jpeg", "image/jpeg"}, + {"animacion.gif", "image/gif"}, + {"imagen.bmp", "image/bmp"}, + {"datos.json", "application/json"}, + {"tabla.csv", "text/csv"}, + {"config.xml", "application/xml"}, + {"nota.txt", "text/plain"}, + {"pagina.html", "text/html"}, + {"archivo.zip", "application/zip"}, + {"archivo.sql", "application/sql"}, + {"archivo.desconocido", "application/octet-stream"}, // unknown extension + {"MAYUSCULAS.JPG", "image/jpeg"}, // upper case + {"MezclaDeMayusculasYMinusculas.PnG", "image/png"}, // mixed case + } + + for _, tt := range tests { + t.Run(tt.fileName, func(t *testing.T) { + result := GetContentTypeFromFileName(tt.fileName) + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/internal/util/strutil/remove_leading_slash.go b/internal/util/strutil/remove_leading_slash.go new file mode 100644 index 0000000..6afd97b --- /dev/null +++ b/internal/util/strutil/remove_leading_slash.go @@ -0,0 +1,10 @@ +package strutil + +// RemoveLeadingSlash removes the leading slash from a string. +func RemoveLeadingSlash(str string) string { + if len(str) > 0 && str[0] == '/' { + return str[1:] + } + + return str +} diff --git a/internal/util/strutil/remove_leading_slash_test.go b/internal/util/strutil/remove_leading_slash_test.go new file mode 100644 index 0000000..486c447 --- /dev/null +++ b/internal/util/strutil/remove_leading_slash_test.go @@ -0,0 +1,50 @@ +package strutil + +import "testing" + +func TestRemoveLeadingSlash(t *testing.T) { + tests := []struct { + name string + str string + want string + }{ + { + name: "Remove leading slash", + str: "/test/", + want: "test/", + }, + { + name: "Remove leading slash from empty string", + str: "", + want: "", + }, + { + name: "Remove leading slash from string without leading slash", + str: "test/", + want: "test/", + }, + { + name: "Remove leading slash from string with multiple leading slashes", + str: "//test/", + want: "/test/", + }, + { + name: "With special characters", + str: "/test/!@#$%^&*()_+/", + want: "test/!@#$%^&*()_+/", + }, + { + name: "With special characters (emojis)", + str: "/test/!@#$%^&*()_+😀/", + want: "test/!@#$%^&*()_+😀/", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := RemoveLeadingSlash(tt.str); got != tt.want { + t.Errorf("RemoveLeadingSlash() = %v, want %v", got, tt.want) + } + }) + } +}