| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- package utils
- import (
- "encoding/base64"
- "net/http"
- "net/http/httptest"
- "net/url"
- "os"
- "strings"
- "testing"
- "time"
- )
- func TestSendTextResponse(t *testing.T) {
- w := httptest.NewRecorder()
- SendTextResponse(w, "Hello, World!")
- if w.Body.String() != "Hello, World!" {
- t.Errorf("Expected: 'Hello, World!', Got: '%s'", w.Body.String())
- }
- }
- func TestSendJSONResponse(t *testing.T) {
- w := httptest.NewRecorder()
- SendJSONResponse(w, `{"key": "value"}`)
- expectedBody := `{"key": "value"}`
- if w.Body.String() != expectedBody {
- t.Errorf("Expected: '%s', Got: '%s'", expectedBody, w.Body.String())
- }
- if w.Header().Get("Content-Type") != "application/json" {
- t.Error("Content-Type header should be set to 'application/json'")
- }
- }
- func TestSendErrorResponse(t *testing.T) {
- w := httptest.NewRecorder()
- SendErrorResponse(w, "Something went wrong")
- expectedBody := `{"error":"Something went wrong"}`
- if w.Body.String() != expectedBody {
- t.Errorf("Expected: '%s', Got: '%s'", expectedBody, w.Body.String())
- }
- if w.Header().Get("Content-Type") != "application/json" {
- t.Error("Content-Type header should be set to 'application/json'")
- }
- }
- func TestSendOK(t *testing.T) {
- w := httptest.NewRecorder()
- SendOK(w)
- expectedBody := `"OK"`
- if w.Body.String() != expectedBody {
- t.Errorf("Expected: '%s', Got: '%s'", expectedBody, w.Body.String())
- }
- if w.Header().Get("Content-Type") != "application/json" {
- t.Error("Content-Type header should be set to 'application/json'")
- }
- }
- func TestTimeToString(t *testing.T) {
- testTime := time.Date(2022, 2, 3, 12, 30, 0, 0, time.UTC)
- result := TimeToString(testTime)
- expectedResult := "2022-02-03 12:30:00"
- if result != expectedResult {
- t.Errorf("Expected: '%s', Got: '%s'", expectedResult, result)
- }
- }
- func TestFileExists(t *testing.T) {
- // Create a temporary file for testing
- tempFile, err := os.CreateTemp("", "testfile.txt")
- tempFile.Close()
- if err != nil {
- t.Fatal(err)
- }
- defer os.Remove(tempFile.Name())
- t.Log(tempFile.Name())
- // Test case 1: Existing file
- exists := FileExists(tempFile.Name())
- if !exists {
- t.Errorf("Test case 1 failed. Expected: true, Got: false")
- }
- // Test case 2: Non-existing file
- err = os.Remove(tempFile.Name())
- if err != nil {
- t.Errorf("OS Remove failed %v", err.Error())
- }
- exists = FileExists(tempFile.Name())
- if exists {
- t.Errorf("Test case 2 failed. Expected: false, Got: true")
- }
- }
- // --- GetPara ---
- func TestGetPara(t *testing.T) {
- req := httptest.NewRequest(http.MethodGet, "/?foo=bar", nil)
- val, err := GetPara(req, "foo")
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if val != "bar" {
- t.Errorf("expected 'bar', got '%s'", val)
- }
- _, err = GetPara(req, "missing")
- if err == nil {
- t.Error("expected error for missing key, got nil")
- }
- }
- // --- GetBool ---
- func TestGetBool(t *testing.T) {
- cases := []struct {
- query string
- key string
- expected bool
- wantErr bool
- }{
- {"?flag=true", "flag", true, false},
- {"?flag=1", "flag", true, false},
- {"?flag=false", "flag", false, false},
- {"?flag=0", "flag", false, false},
- {"?flag=yes", "flag", false, true},
- {"", "flag", false, true},
- }
- for _, tc := range cases {
- req := httptest.NewRequest(http.MethodGet, "/"+tc.query, nil)
- got, err := GetBool(req, tc.key)
- if tc.wantErr {
- if err == nil {
- t.Errorf("query=%q key=%q: expected error, got nil", tc.query, tc.key)
- }
- } else {
- if err != nil {
- t.Errorf("query=%q key=%q: unexpected error: %v", tc.query, tc.key, err)
- }
- if got != tc.expected {
- t.Errorf("query=%q key=%q: expected %v, got %v", tc.query, tc.key, tc.expected, got)
- }
- }
- }
- }
- // --- GetInt ---
- func TestGetInt(t *testing.T) {
- req := httptest.NewRequest(http.MethodGet, "/?n=42", nil)
- val, err := GetInt(req, "n")
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if val != 42 {
- t.Errorf("expected 42, got %d", val)
- }
- req2 := httptest.NewRequest(http.MethodGet, "/?n=abc", nil)
- _, err = GetInt(req2, "n")
- if err == nil {
- t.Error("expected error for non-integer value")
- }
- req3 := httptest.NewRequest(http.MethodGet, "/", nil)
- _, err = GetInt(req3, "n")
- if err == nil {
- t.Error("expected error for missing key")
- }
- }
- // --- PostPara ---
- func TestPostPara(t *testing.T) {
- form := url.Values{}
- form.Set("name", "alice")
- req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(form.Encode()))
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- val, err := PostPara(req, "name")
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if val != "alice" {
- t.Errorf("expected 'alice', got '%s'", val)
- }
- _, err = PostPara(req, "missing")
- if err == nil {
- t.Error("expected error for missing key, got nil")
- }
- }
- // --- PostBool ---
- func TestPostBool(t *testing.T) {
- cases := []struct {
- formVal string
- expected bool
- wantErr bool
- }{
- {"true", true, false},
- {"1", true, false},
- {"false", false, false},
- {"0", false, false},
- {"maybe", false, true},
- }
- for _, tc := range cases {
- form := url.Values{}
- form.Set("flag", tc.formVal)
- req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(form.Encode()))
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- got, err := PostBool(req, "flag")
- if tc.wantErr {
- if err == nil {
- t.Errorf("formVal=%q: expected error, got nil", tc.formVal)
- }
- } else {
- if err != nil {
- t.Errorf("formVal=%q: unexpected error: %v", tc.formVal, err)
- }
- if got != tc.expected {
- t.Errorf("formVal=%q: expected %v, got %v", tc.formVal, tc.expected, got)
- }
- }
- }
- // Missing key
- req := httptest.NewRequest(http.MethodPost, "/", nil)
- _, err := PostBool(req, "flag")
- if err == nil {
- t.Error("expected error for missing key")
- }
- }
- // --- PostInt ---
- func TestPostInt(t *testing.T) {
- form := url.Values{}
- form.Set("count", "7")
- req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(form.Encode()))
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- val, err := PostInt(req, "count")
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- if val != 7 {
- t.Errorf("expected 7, got %d", val)
- }
- // Non-integer value
- form2 := url.Values{}
- form2.Set("count", "notanint")
- req2 := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(form2.Encode()))
- req2.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- _, err = PostInt(req2, "count")
- if err == nil {
- t.Error("expected error for non-integer value")
- }
- // Missing key
- req3 := httptest.NewRequest(http.MethodPost, "/", nil)
- _, err = PostInt(req3, "count")
- if err == nil {
- t.Error("expected error for missing key")
- }
- }
- // --- IsDir ---
- func TestIsDir(t *testing.T) {
- dir, err := os.MkdirTemp("", "testdir")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(dir)
- if !IsDir(dir) {
- t.Errorf("expected IsDir=true for directory %s", dir)
- }
- tmpFile, err := os.CreateTemp(dir, "file")
- if err != nil {
- t.Fatal(err)
- }
- tmpFile.Close()
- if IsDir(tmpFile.Name()) {
- t.Errorf("expected IsDir=false for regular file %s", tmpFile.Name())
- }
- if IsDir("/nonexistent/path/xyz") {
- t.Error("expected IsDir=false for non-existent path")
- }
- }
- // --- LoadImageAsBase64 ---
- func TestLoadImageAsBase64(t *testing.T) {
- // Write some bytes to a temp file and verify roundtrip
- content := []byte{0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A} // PNG magic bytes
- tmpFile, err := os.CreateTemp("", "img*.png")
- if err != nil {
- t.Fatal(err)
- }
- defer os.Remove(tmpFile.Name())
- if _, err := tmpFile.Write(content); err != nil {
- t.Fatal(err)
- }
- tmpFile.Close()
- encoded, err := LoadImageAsBase64(tmpFile.Name())
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- decoded, err := base64.StdEncoding.DecodeString(encoded)
- if err != nil {
- t.Fatalf("failed to decode base64: %v", err)
- }
- if string(decoded) != string(content) {
- t.Errorf("decoded content mismatch: expected %v, got %v", content, decoded)
- }
- // Non-existent file
- _, err = LoadImageAsBase64("/nonexistent/image.png")
- if err == nil {
- t.Error("expected error for non-existent file")
- }
- }
- // --- ConstructRelativePathFromRequestURL ---
- func TestConstructRelativePathFromRequestURL(t *testing.T) {
- cases := []struct {
- requestURI string
- location string
- expected string
- }{
- // Root level: only one slash, no prepend
- {"/page", "index.html", "index.html"},
- // One level deep: one extra slash --> one "../"
- {"/section/page", "index.html", "../index.html"},
- // Two levels deep: two extra slashes --> two "../"
- {"/a/b/page", "index.html", "../../index.html"},
- }
- for _, tc := range cases {
- got := ConstructRelativePathFromRequestURL(tc.requestURI, tc.location)
- if got != tc.expected {
- t.Errorf("requestURI=%q location=%q: expected %q, got %q",
- tc.requestURI, tc.location, tc.expected, got)
- }
- }
- }
- // --- StringInArray ---
- func TestStringInArray(t *testing.T) {
- arr := []string{"apple", "banana", "cherry"}
- if !StringInArray(arr, "banana") {
- t.Error("expected 'banana' to be found in array")
- }
- if StringInArray(arr, "Banana") {
- t.Error("expected case-sensitive check to fail for 'Banana'")
- }
- if StringInArray(arr, "mango") {
- t.Error("expected 'mango' not to be found in array")
- }
- if StringInArray([]string{}, "apple") {
- t.Error("expected false for empty array")
- }
- }
- // --- StringInArrayIgnoreCase ---
- func TestStringInArrayIgnoreCase(t *testing.T) {
- arr := []string{"Apple", "Banana", "Cherry"}
- if !StringInArrayIgnoreCase(arr, "apple") {
- t.Error("expected 'apple' to be found (case-insensitive)")
- }
- if !StringInArrayIgnoreCase(arr, "BANANA") {
- t.Error("expected 'BANANA' to be found (case-insensitive)")
- }
- if StringInArrayIgnoreCase(arr, "mango") {
- t.Error("expected 'mango' not to be found")
- }
- if StringInArrayIgnoreCase([]string{}, "apple") {
- t.Error("expected false for empty array")
- }
- }
- // --- Templateload ---
- func TestTemplateload(t *testing.T) {
- content := "Hello, {{name}}! You are {{age}} years old."
- tmpFile, err := os.CreateTemp("", "template*.html")
- if err != nil {
- t.Fatal(err)
- }
- defer os.Remove(tmpFile.Name())
- if _, err := tmpFile.WriteString(content); err != nil {
- t.Fatal(err)
- }
- tmpFile.Close()
- data := map[string]string{
- "name": "Alice",
- "age": "30",
- }
- result, err := Templateload(tmpFile.Name(), data)
- if err != nil {
- t.Fatalf("unexpected error: %v", err)
- }
- expected := "Hello, Alice! You are 30 years old."
- if result != expected {
- t.Errorf("expected %q, got %q", expected, result)
- }
- // Non-existent template file
- _, err = Templateload("/nonexistent/template.html", data)
- if err == nil {
- t.Error("expected error for non-existent template file")
- }
- }
- // --- TemplateApply ---
- func TestTemplateApply(t *testing.T) {
- tmpl := "Dear {{title}} {{surname}}, welcome to {{place}}."
- data := map[string]string{
- "title": "Dr.",
- "surname": "Smith",
- "place": "ArozOS",
- }
- result := TemplateApply(tmpl, data)
- expected := "Dear Dr. Smith, welcome to ArozOS."
- if result != expected {
- t.Errorf("expected %q, got %q", expected, result)
- }
- // No replacements needed
- plain := "No placeholders here."
- result2 := TemplateApply(plain, map[string]string{})
- if result2 != plain {
- t.Errorf("expected unchanged string %q, got %q", plain, result2)
- }
- // Placeholder that doesn't exist in data is left intact
- partial := "Hello {{name}}, your code is {{code}}."
- result3 := TemplateApply(partial, map[string]string{"name": "Bob"})
- if result3 != "Hello Bob, your code is {{code}}." {
- t.Errorf("unexpected result for partial replacement: %q", result3)
- }
- }
- // --- FilenameIsWebSafe ---
- func TestFilenameIsWebSafe(t *testing.T) {
- safeNames := []string{
- "myfile.txt",
- "image-001.png",
- "document_v2.pdf",
- "report 2024.docx",
- }
- for _, name := range safeNames {
- if !FilenameIsWebSafe(name) {
- t.Errorf("expected %q to be web-safe", name)
- }
- }
- unsafeNames := []string{
- "file/with/slashes.txt",
- "back\\slash.txt",
- "query?param=1",
- "percent%20encoded",
- "wild*card",
- "colon:name",
- "pipe|name",
- `quote"name`,
- "less<than",
- "greater>than",
- }
- for _, name := range unsafeNames {
- if FilenameIsWebSafe(name) {
- t.Errorf("expected %q to be NOT web-safe", name)
- }
- }
- }
|