aliases_test.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. package main
  2. import (
  3. "io"
  4. "os"
  5. "testing"
  6. "github.com/rs/zerolog"
  7. )
  8. func init() {
  9. // Initialize logger for tests to prevent nil pointer dereference
  10. logger := zerolog.New(io.Discard).With().Timestamp().Logger()
  11. log = &logger
  12. }
  13. func TestAliasLoadFile(t *testing.T) {
  14. tests := []struct {
  15. name string
  16. content string
  17. expected AliasMap
  18. expectError bool
  19. }{
  20. {
  21. name: "valid aliases",
  22. content: "user1 alias1\nuser2 alias2\nuser3 alias3",
  23. expected: AliasMap{
  24. "user1": "alias1",
  25. "user2": "alias2",
  26. "user3": "alias3",
  27. },
  28. expectError: false,
  29. },
  30. {
  31. name: "empty file",
  32. content: "",
  33. expected: AliasMap{},
  34. expectError: false,
  35. },
  36. {
  37. name: "file with empty lines",
  38. content: "user1 alias1\n\nuser2 alias2\n\n",
  39. expected: AliasMap{
  40. "user1": "alias1",
  41. "user2": "alias2",
  42. },
  43. expectError: false,
  44. },
  45. {
  46. name: "file with whitespace",
  47. content: " user1 alias1 \n\t user2\talias2\t",
  48. expected: AliasMap{
  49. "user1": "alias1",
  50. "user2": "alias2",
  51. },
  52. expectError: false,
  53. },
  54. {
  55. name: "extra fields ignored",
  56. content: "user1 alias1 extra field\nuser2 alias2",
  57. expected: AliasMap{
  58. "user1": "alias1",
  59. "user2": "alias2",
  60. },
  61. expectError: false,
  62. },
  63. {
  64. name: "single field line ignored",
  65. content: "user1\nuser2 alias2",
  66. expected: AliasMap{"user2": "alias2"},
  67. expectError: false,
  68. },
  69. }
  70. for _, tt := range tests {
  71. t.Run(tt.name, func(t *testing.T) {
  72. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  73. if err != nil {
  74. t.Fatalf("failed to create temp file: %v", err)
  75. }
  76. defer os.Remove(tmpFile.Name())
  77. if _, err := tmpFile.WriteString(tt.content); err != nil {
  78. t.Fatalf("failed to write to temp file: %v", err)
  79. }
  80. tmpFile.Close()
  81. result, err := AliasLoadFile(tmpFile.Name())
  82. if tt.expectError && err == nil {
  83. t.Error("expected error but got none")
  84. }
  85. if !tt.expectError && err != nil {
  86. t.Errorf("unexpected error: %v", err)
  87. }
  88. if len(result) != len(tt.expected) {
  89. t.Errorf("expected %d aliases, got %d", len(tt.expected), len(result))
  90. }
  91. for key, expectedValue := range tt.expected {
  92. if actualValue, exists := result[key]; !exists {
  93. t.Errorf("expected key %q not found", key)
  94. } else if actualValue != expectedValue {
  95. t.Errorf("for key %q: expected %q, got %q", key, expectedValue, actualValue)
  96. }
  97. }
  98. })
  99. }
  100. }
  101. func TestLoadAliases(t *testing.T) {
  102. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  103. if err != nil {
  104. t.Fatalf("failed to create temp file: %v", err)
  105. }
  106. defer os.Remove(tmpFile.Name())
  107. content := "user1 alias1\nuser2 alias2"
  108. if _, err := tmpFile.WriteString(content); err != nil {
  109. t.Fatalf("failed to write to temp file: %v", err)
  110. }
  111. tmpFile.Close()
  112. err = LoadAliases(tmpFile.Name())
  113. if err != nil {
  114. t.Errorf("unexpected error: %v", err)
  115. }
  116. aliasesMutex.RLock()
  117. defer aliasesMutex.RUnlock()
  118. if len(aliasesList) != 2 {
  119. t.Errorf("expected 2 aliases, got %d", len(aliasesList))
  120. }
  121. if aliasesList["user1"] != "alias1" {
  122. t.Errorf("expected user1 -> alias1, got %q", aliasesList["user1"])
  123. }
  124. if aliasesList["user2"] != "alias2" {
  125. t.Errorf("expected user2 -> alias2, got %q", aliasesList["user2"])
  126. }
  127. }
  128. func TestLoadAliases_EmptyFile(t *testing.T) {
  129. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  130. if err != nil {
  131. t.Fatalf("failed to create temp file: %v", err)
  132. }
  133. defer os.Remove(tmpFile.Name())
  134. tmpFile.Close()
  135. err = LoadAliases(tmpFile.Name())
  136. if err != nil {
  137. t.Errorf("unexpected error: %v", err)
  138. }
  139. aliasesMutex.RLock()
  140. defer aliasesMutex.RUnlock()
  141. if len(aliasesList) != 0 {
  142. t.Errorf("expected 0 aliases, got %d", len(aliasesList))
  143. }
  144. }
  145. func TestLoadAliases_UpdatesExistingAliases(t *testing.T) {
  146. // First load
  147. tmpFile1, err := os.CreateTemp("", "aliases-*.txt")
  148. if err != nil {
  149. t.Fatalf("failed to create temp file: %v", err)
  150. }
  151. defer os.Remove(tmpFile1.Name())
  152. content1 := "user1 alias1\nuser2 alias2"
  153. if _, err := tmpFile1.WriteString(content1); err != nil {
  154. t.Fatalf("failed to write to temp file: %v", err)
  155. }
  156. tmpFile1.Close()
  157. err = LoadAliases(tmpFile1.Name())
  158. if err != nil {
  159. t.Errorf("unexpected error: %v", err)
  160. }
  161. // Second load with different content
  162. tmpFile2, err := os.CreateTemp("", "aliases-*.txt")
  163. if err != nil {
  164. t.Fatalf("failed to create temp file: %v", err)
  165. }
  166. defer os.Remove(tmpFile2.Name())
  167. content2 := "user3 alias3"
  168. if _, err := tmpFile2.WriteString(content2); err != nil {
  169. t.Fatalf("failed to write to temp file: %v", err)
  170. }
  171. tmpFile2.Close()
  172. err = LoadAliases(tmpFile2.Name())
  173. if err != nil {
  174. t.Errorf("unexpected error: %v", err)
  175. }
  176. aliasesMutex.RLock()
  177. defer aliasesMutex.RUnlock()
  178. if len(aliasesList) != 1 {
  179. t.Errorf("expected 1 alias after reload, got %d", len(aliasesList))
  180. }
  181. if aliasesList["user3"] != "alias3" {
  182. t.Errorf("expected user3 -> alias3, got %q", aliasesList["user3"])
  183. }
  184. if _, exists := aliasesList["user1"]; exists {
  185. t.Error("expected user1 to be removed after reload")
  186. }
  187. }
  188. func TestAliasLoadFile_MultipleSpaces(t *testing.T) {
  189. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  190. if err != nil {
  191. t.Fatalf("failed to create temp file: %v", err)
  192. }
  193. defer os.Remove(tmpFile.Name())
  194. content := "user1 alias1\nuser2 alias2"
  195. if _, err := tmpFile.WriteString(content); err != nil {
  196. t.Fatalf("failed to write to temp file: %v", err)
  197. }
  198. tmpFile.Close()
  199. result, err := AliasLoadFile(tmpFile.Name())
  200. if err != nil {
  201. t.Errorf("unexpected error: %v", err)
  202. }
  203. if result["user1"] != "alias1" {
  204. t.Errorf("expected user1 -> alias1, got %q", result["user1"])
  205. }
  206. if result["user2"] != "alias2" {
  207. t.Errorf("expected user2 -> alias2, got %q", result["user2"])
  208. }
  209. }
  210. func TestAliasLoadFile_TabSeparated(t *testing.T) {
  211. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  212. if err != nil {
  213. t.Fatalf("failed to create temp file: %v", err)
  214. }
  215. defer os.Remove(tmpFile.Name())
  216. content := "user1\talias1\nuser2\t\talias2"
  217. if _, err := tmpFile.WriteString(content); err != nil {
  218. t.Fatalf("failed to write to temp file: %v", err)
  219. }
  220. tmpFile.Close()
  221. result, err := AliasLoadFile(tmpFile.Name())
  222. if err != nil {
  223. t.Errorf("unexpected error: %v", err)
  224. }
  225. if len(result) != 2 {
  226. t.Errorf("expected 2 aliases, got %d", len(result))
  227. }
  228. }
  229. func TestAliasLoadFile_DuplicateKeys(t *testing.T) {
  230. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  231. if err != nil {
  232. t.Fatalf("failed to create temp file: %v", err)
  233. }
  234. defer os.Remove(tmpFile.Name())
  235. content := "user1 alias1\nuser1 alias2\nuser1 alias3"
  236. if _, err := tmpFile.WriteString(content); err != nil {
  237. t.Fatalf("failed to write to temp file: %v", err)
  238. }
  239. tmpFile.Close()
  240. result, err := AliasLoadFile(tmpFile.Name())
  241. if err != nil {
  242. t.Errorf("unexpected error: %v", err)
  243. }
  244. if len(result) != 1 {
  245. t.Errorf("expected 1 alias (last one wins), got %d", len(result))
  246. }
  247. if result["user1"] != "alias3" {
  248. t.Errorf("expected user1 -> alias3 (last one), got %q", result["user1"])
  249. }
  250. }
  251. func TestAliasLoadFile_OnlyWhitespace(t *testing.T) {
  252. tmpFile, err := os.CreateTemp("", "aliases-*.txt")
  253. if err != nil {
  254. t.Fatalf("failed to create temp file: %v", err)
  255. }
  256. defer os.Remove(tmpFile.Name())
  257. content := " \n\t\t\n \t \n"
  258. if _, err := tmpFile.WriteString(content); err != nil {
  259. t.Fatalf("failed to write to temp file: %v", err)
  260. }
  261. tmpFile.Close()
  262. result, err := AliasLoadFile(tmpFile.Name())
  263. if err != nil {
  264. t.Errorf("unexpected error: %v", err)
  265. }
  266. if len(result) != 0 {
  267. t.Errorf("expected 0 aliases, got %d", len(result))
  268. }
  269. }