This is a simple URL shortener
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

386 lines
8.4KB

  1. package db_test
  2. import (
  3. "os"
  4. "testing"
  5. "gitea.nefixestrada.com/nefix/urlshortener/pkg/db"
  6. bolt "go.etcd.io/bbolt"
  7. )
  8. var tests = []struct {
  9. shortURL string
  10. longURL string
  11. }{
  12. {
  13. shortURL: "git",
  14. longURL: "https://gitea.nefixestrada.com",
  15. },
  16. }
  17. // Should work as expected
  18. func TestReadURL(t *testing.T) {
  19. for _, tt := range tests {
  20. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  21. if err != nil {
  22. t.Fatalf("error creating the testing DB: %v", err)
  23. }
  24. if err = boltDB.Update(func(tx *bolt.Tx) error {
  25. var b *bolt.Bucket
  26. b, err = tx.CreateBucket([]byte("urls"))
  27. if err != nil {
  28. return err
  29. }
  30. if err = b.Put([]byte(tt.shortURL), []byte(tt.longURL)); err != nil {
  31. return err
  32. }
  33. return nil
  34. }); err != nil {
  35. t.Fatalf("error inserting test data to the DB: %v", err)
  36. }
  37. db := db.DB{
  38. DB: boltDB,
  39. }
  40. rsp, err := db.ReadURL(tt.shortURL)
  41. if err != nil {
  42. t.Errorf("unexpected error when reading the URL in the DB: %v", err)
  43. }
  44. if rsp != tt.longURL {
  45. t.Errorf("expecting %s, but got %s", tt.shortURL, tt.longURL)
  46. }
  47. if err := os.Remove("urlshortener.db"); err != nil {
  48. t.Fatalf("error finishing the test: %v", err)
  49. }
  50. }
  51. }
  52. // Should return a not found error
  53. func TestReadURLNotFound(t *testing.T) {
  54. for _, tt := range tests {
  55. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  56. if err != nil {
  57. t.Fatalf("error creating the testing DB: %v", err)
  58. }
  59. if err = boltDB.Update(func(tx *bolt.Tx) error {
  60. _, err = tx.CreateBucket([]byte("urls"))
  61. return err
  62. }); err != nil {
  63. t.Fatalf("error inserting test data to the DB: %v", err)
  64. }
  65. db := db.DB{
  66. DB: boltDB,
  67. }
  68. expectedErr := "the shortened URL wasn't found in the DB"
  69. rsp, err := db.ReadURL(tt.shortURL)
  70. if err.Error() != expectedErr {
  71. t.Errorf("expecting %s, but got %v", expectedErr, err)
  72. }
  73. if rsp != "" {
  74. t.Errorf("expecting %s, but got %s", "", rsp)
  75. }
  76. if err := os.Remove("urlshortener.db"); err != nil {
  77. t.Fatalf("error finishing the test: %v", err)
  78. }
  79. }
  80. }
  81. // Should work as expected
  82. func TestAddURL(t *testing.T) {
  83. for _, tt := range tests {
  84. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  85. if err != nil {
  86. t.Fatalf("error creating the testing DB: %v", err)
  87. }
  88. if err = boltDB.Update(func(tx *bolt.Tx) error {
  89. _, err = tx.CreateBucket([]byte("urls"))
  90. return err
  91. }); err != nil {
  92. t.Fatalf("error inserting test data to the DB: %v", err)
  93. }
  94. db := db.DB{
  95. DB: boltDB,
  96. }
  97. err = db.AddURL(tt.shortURL, tt.longURL)
  98. if err != nil {
  99. t.Errorf("unexpected error adding the URL: %v", err)
  100. }
  101. if err := os.Remove("urlshortener.db"); err != nil {
  102. t.Fatalf("error finishing the test: %v", err)
  103. }
  104. }
  105. }
  106. // The short URL can't be empty
  107. func TestAddURLShortNoEmpty(t *testing.T) {
  108. for _, tt := range tests {
  109. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  110. if err != nil {
  111. t.Fatalf("error creating the testing DB: %v", err)
  112. }
  113. if err = boltDB.Update(func(tx *bolt.Tx) error {
  114. _, err = tx.CreateBucket([]byte("urls"))
  115. return err
  116. }); err != nil {
  117. t.Fatalf("error inserting test data to the DB: %v", err)
  118. }
  119. db := db.DB{
  120. DB: boltDB,
  121. }
  122. expectedErr := "the short URL can't be empty"
  123. err = db.AddURL("", tt.longURL)
  124. if err.Error() != expectedErr {
  125. t.Errorf("expecting %s, but got %v", expectedErr, err)
  126. }
  127. if err := os.Remove("urlshortener.db"); err != nil {
  128. t.Fatalf("error finishing the test: %v", err)
  129. }
  130. }
  131. }
  132. // The long URL can't be empty
  133. func TestAddURLLongNoEmpty(t *testing.T) {
  134. for _, tt := range tests {
  135. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  136. if err != nil {
  137. t.Fatalf("error creating the testing DB: %v", err)
  138. }
  139. if err = boltDB.Update(func(tx *bolt.Tx) error {
  140. _, err = tx.CreateBucket([]byte("urls"))
  141. return err
  142. }); err != nil {
  143. t.Fatalf("error inserting test data to the DB: %v", err)
  144. }
  145. db := db.DB{
  146. DB: boltDB,
  147. }
  148. expectedErr := "the long URL can't be empty"
  149. err = db.AddURL(tt.shortURL, "")
  150. if err.Error() != expectedErr {
  151. t.Errorf("expecting %s, but got %v", expectedErr, err)
  152. }
  153. if err := os.Remove("urlshortener.db"); err != nil {
  154. t.Fatalf("error finishing the test: %v", err)
  155. }
  156. }
  157. }
  158. // The long URL needs to be an URL
  159. func TestAddURLLongIsURL(t *testing.T) {
  160. for _, tt := range tests {
  161. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  162. if err != nil {
  163. t.Fatalf("error creating the testing DB: %v", err)
  164. }
  165. if err = boltDB.Update(func(tx *bolt.Tx) error {
  166. _, err = tx.CreateBucket([]byte("urls"))
  167. return err
  168. }); err != nil {
  169. t.Fatalf("error inserting test data to the DB: %v", err)
  170. }
  171. db := db.DB{
  172. DB: boltDB,
  173. }
  174. expectedErr := "the long URL needs to be a valid URL"
  175. err = db.AddURL(tt.shortURL, "https://notanurl!")
  176. if err.Error() != expectedErr {
  177. t.Errorf("expecting %s, but got %v", expectedErr, err)
  178. }
  179. if err := os.Remove("urlshortener.db"); err != nil {
  180. t.Fatalf("error finishing the test: %v", err)
  181. }
  182. }
  183. }
  184. // The bucket 'urls' doesn't exist
  185. func TestAddURLBucketNotExist(t *testing.T) {
  186. for _, tt := range tests {
  187. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  188. if err != nil {
  189. t.Fatalf("error creating the testing DB: %v", err)
  190. }
  191. db := db.DB{
  192. DB: boltDB,
  193. }
  194. expectedErr := "the bucket urls doesn't exist"
  195. err = db.AddURL(tt.shortURL, tt.longURL)
  196. if err.Error() != expectedErr {
  197. t.Errorf("expecting %s, but got %v", expectedErr, err)
  198. }
  199. if err := os.Remove("urlshortener.db"); err != nil {
  200. t.Fatalf("error finishing the test: %v", err)
  201. }
  202. }
  203. }
  204. // The shortened URL already exists
  205. func TestAddURLAlreadyExists(t *testing.T) {
  206. for _, tt := range tests {
  207. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  208. if err != nil {
  209. t.Fatalf("error creating the testing DB: %v", err)
  210. }
  211. if err = boltDB.Update(func(tx *bolt.Tx) error {
  212. var b *bolt.Bucket
  213. b, err = tx.CreateBucket([]byte("urls"))
  214. if err != nil {
  215. return err
  216. }
  217. if err = b.Put([]byte(tt.shortURL), []byte(tt.longURL)); err != nil {
  218. return err
  219. }
  220. return nil
  221. }); err != nil {
  222. t.Fatalf("error inserting test data to the DB: %v", err)
  223. }
  224. db := db.DB{
  225. DB: boltDB,
  226. }
  227. expectedErr := "there's already an shortened URL with that URL"
  228. err = db.AddURL(tt.shortURL, tt.longURL)
  229. if err.Error() != expectedErr {
  230. t.Errorf("expecting %s, but got %v", expectedErr, err)
  231. }
  232. if err := os.Remove("urlshortener.db"); err != nil {
  233. t.Fatalf("error finishing the test: %v", err)
  234. }
  235. }
  236. }
  237. // There should be an error when inserting the URL in the DB
  238. func TestAddURLErrInserting(t *testing.T) {
  239. for _, tt := range tests {
  240. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  241. if err != nil {
  242. t.Fatalf("error creating the testing DB: %v", err)
  243. }
  244. if err = boltDB.Update(func(tx *bolt.Tx) error {
  245. _, err = tx.CreateBucket([]byte("urls"))
  246. return err
  247. }); err != nil {
  248. t.Fatalf("error inserting test data to the DB: %v", err)
  249. }
  250. db := db.DB{
  251. DB: boltDB,
  252. }
  253. expectedErr := "key too large"
  254. longKey := make([]byte, bolt.MaxKeySize+1)
  255. err = db.AddURL(string(longKey), tt.longURL)
  256. if err.Error() != expectedErr {
  257. t.Errorf("expecting %s, but got %v", expectedErr, err)
  258. }
  259. if err := os.Remove("urlshortener.db"); err != nil {
  260. t.Fatalf("error finishing the test: %v", err)
  261. }
  262. }
  263. }
  264. // Should work as expected
  265. func TestInitialize(t *testing.T) {
  266. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  267. if err != nil {
  268. t.Fatalf("error creating the testing DB: %v", err)
  269. }
  270. db := db.DB{
  271. DB: boltDB,
  272. }
  273. err = db.Initialize()
  274. if err != nil {
  275. t.Errorf("unexpected error initializing the DB: %v", err)
  276. }
  277. if err = boltDB.Update(func(tx *bolt.Tx) error {
  278. _, err = tx.CreateBucket([]byte("urls"))
  279. return err
  280. }); err != bolt.ErrBucketExists {
  281. t.Errorf("expecting %v, but got %v", bolt.ErrBucketExists, err)
  282. }
  283. if err := os.Remove("urlshortener.db"); err != nil {
  284. t.Fatalf("error finishing the test: %v", err)
  285. }
  286. }
  287. // There should be an error creating the bucket
  288. func TestInitializeErrBucket(t *testing.T) {
  289. boltDB, err := bolt.Open("urlshortener.db", 0600, nil)
  290. if err != nil {
  291. t.Fatalf("error creating the testing DB: %v", err)
  292. }
  293. db := db.DB{
  294. DB: boltDB,
  295. }
  296. db.DB.Close()
  297. expectedErr := "database not open"
  298. err = db.Initialize()
  299. if err.Error() != expectedErr {
  300. t.Errorf("expecting %s, but got %v", expectedErr, err)
  301. }
  302. if err := os.Remove("urlshortener.db"); err != nil {
  303. t.Fatalf("error finishing the test: %v", err)
  304. }
  305. }