Contains the Concourse pipeline definition for building a line-server container
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.

699 lines
15 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package main
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "mime/multipart"
  6. "net/http"
  7. "net/http/httptest"
  8. "net/url"
  9. "os"
  10. "path"
  11. "strconv"
  12. "strings"
  13. "testing"
  14. "time"
  15. "github.com/zenazn/goji"
  16. )
  17. type RespOkJSON struct {
  18. Filename string
  19. Url string
  20. Delete_Key string
  21. Expiry string
  22. Size string
  23. }
  24. type RespErrJSON struct {
  25. Error string
  26. }
  27. func TestSetup(t *testing.T) {
  28. Config.siteURL = "http://linx.example.org/"
  29. Config.filesDir = path.Join(os.TempDir(), generateBarename())
  30. Config.metaDir = Config.filesDir + "_meta"
  31. Config.noLogs = true
  32. Config.siteName = "linx"
  33. setup()
  34. }
  35. func TestIndex(t *testing.T) {
  36. w := httptest.NewRecorder()
  37. req, err := http.NewRequest("GET", "/", nil)
  38. if err != nil {
  39. t.Fatal(err)
  40. }
  41. goji.DefaultMux.ServeHTTP(w, req)
  42. if !strings.Contains(w.Body.String(), "Click or Drop file") {
  43. t.Fatal("String 'Click or Drop file' not found in index response")
  44. }
  45. }
  46. func TestNotFound(t *testing.T) {
  47. w := httptest.NewRecorder()
  48. req, err := http.NewRequest("GET", "/url/should/not/exist", nil)
  49. if err != nil {
  50. t.Fatal(err)
  51. }
  52. goji.DefaultMux.ServeHTTP(w, req)
  53. if w.Code != 404 {
  54. t.Fatalf("Expected 404, got %d", w.Code)
  55. }
  56. }
  57. func TestFileNotFound(t *testing.T) {
  58. w := httptest.NewRecorder()
  59. filename := generateBarename()
  60. req, err := http.NewRequest("GET", "/selif/"+filename, nil)
  61. if err != nil {
  62. t.Fatal(err)
  63. }
  64. goji.DefaultMux.ServeHTTP(w, req)
  65. if w.Code != 404 {
  66. t.Fatalf("Expected 404, got %d", w.Code)
  67. }
  68. }
  69. func TestDisplayNotFound(t *testing.T) {
  70. w := httptest.NewRecorder()
  71. filename := generateBarename()
  72. req, err := http.NewRequest("GET", "/"+filename, nil)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. goji.DefaultMux.ServeHTTP(w, req)
  77. if w.Code != 404 {
  78. t.Fatalf("Expected 404, got %d", w.Code)
  79. }
  80. }
  81. func TestPostCodeUpload(t *testing.T) {
  82. w := httptest.NewRecorder()
  83. filename := generateBarename()
  84. extension := "txt"
  85. form := url.Values{}
  86. form.Add("content", "File content")
  87. form.Add("filename", filename)
  88. form.Add("extension", extension)
  89. req, err := http.NewRequest("POST", "/upload/", nil)
  90. if err != nil {
  91. t.Fatal(err)
  92. }
  93. req.PostForm = form
  94. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  95. goji.DefaultMux.ServeHTTP(w, req)
  96. if w.Code != 301 {
  97. t.Fatalf("Status code is not 301, but %d", w.Code)
  98. }
  99. if w.Header().Get("Location") != "/"+filename+"."+extension {
  100. t.Fatalf("Was redirected to %s instead of /%s", w.Header().Get("Location"), filename)
  101. }
  102. }
  103. func TestPostCodeExpiryJSONUpload(t *testing.T) {
  104. w := httptest.NewRecorder()
  105. form := url.Values{}
  106. form.Add("content", "File content")
  107. form.Add("filename", "")
  108. form.Add("expires", "60")
  109. req, err := http.NewRequest("POST", "/upload/", nil)
  110. if err != nil {
  111. t.Fatal(err)
  112. }
  113. req.PostForm = form
  114. req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
  115. req.Header.Set("Accept", "application/json")
  116. goji.DefaultMux.ServeHTTP(w, req)
  117. if w.Code != 200 {
  118. t.Log(w.Body.String())
  119. t.Fatalf("Status code is not 200, but %d", w.Code)
  120. }
  121. var myjson RespOkJSON
  122. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  123. if err != nil {
  124. t.Fatal(err)
  125. }
  126. myExp, err := strconv.ParseInt(myjson.Expiry, 10, 64)
  127. if err != nil {
  128. t.Fatal(err)
  129. }
  130. curTime := time.Now().Unix()
  131. if myExp < curTime {
  132. t.Fatalf("File expiry (%d) is smaller than current time (%d)", myExp, curTime)
  133. }
  134. if myjson.Size != "12" {
  135. t.Fatalf("File size was not 12 but %s", myjson.Size)
  136. }
  137. }
  138. func TestPostUpload(t *testing.T) {
  139. w := httptest.NewRecorder()
  140. filename := generateBarename() + ".txt"
  141. var b bytes.Buffer
  142. mw := multipart.NewWriter(&b)
  143. fw, err := mw.CreateFormFile("file", filename)
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. fw.Write([]byte("File content"))
  148. mw.Close()
  149. req, err := http.NewRequest("POST", "/upload/", &b)
  150. req.Header.Set("Content-Type", mw.FormDataContentType())
  151. if err != nil {
  152. t.Fatal(err)
  153. }
  154. goji.DefaultMux.ServeHTTP(w, req)
  155. if w.Code != 301 {
  156. t.Fatalf("Status code is not 301, but %d", w.Code)
  157. }
  158. if w.Header().Get("Location") != "/"+filename {
  159. t.Fatalf("Was redirected to %s instead of /%s", w.Header().Get("Location"), filename)
  160. }
  161. }
  162. func TestPostJSONUpload(t *testing.T) {
  163. w := httptest.NewRecorder()
  164. filename := generateBarename() + ".txt"
  165. var b bytes.Buffer
  166. mw := multipart.NewWriter(&b)
  167. fw, err := mw.CreateFormFile("file", filename)
  168. if err != nil {
  169. t.Fatal(err)
  170. }
  171. fw.Write([]byte("File content"))
  172. mw.Close()
  173. req, err := http.NewRequest("POST", "/upload/", &b)
  174. req.Header.Set("Content-Type", mw.FormDataContentType())
  175. req.Header.Set("Accept", "application/json")
  176. if err != nil {
  177. t.Fatal(err)
  178. }
  179. goji.DefaultMux.ServeHTTP(w, req)
  180. if w.Code != 200 {
  181. t.Log(w.Body.String())
  182. t.Fatalf("Status code is not 200, but %d", w.Code)
  183. }
  184. var myjson RespOkJSON
  185. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  186. if err != nil {
  187. t.Fatal(err)
  188. }
  189. if myjson.Filename != filename {
  190. t.Fatalf("Filename is not '%s' but '%s' ", filename, myjson.Filename)
  191. }
  192. if myjson.Expiry != "0" {
  193. t.Fatalf("File expiry is not 0 but %s", myjson.Expiry)
  194. }
  195. if myjson.Size != "12" {
  196. t.Fatalf("File size was not 12 but %s", myjson.Size)
  197. }
  198. }
  199. func TestPostExpiresJSONUpload(t *testing.T) {
  200. w := httptest.NewRecorder()
  201. filename := generateBarename() + ".txt"
  202. var b bytes.Buffer
  203. mw := multipart.NewWriter(&b)
  204. fw, err := mw.CreateFormFile("file", filename)
  205. if err != nil {
  206. t.Fatal(err)
  207. }
  208. fw.Write([]byte("File content"))
  209. exp, err := mw.CreateFormField("expires")
  210. if err != nil {
  211. t.Fatal(err)
  212. }
  213. exp.Write([]byte("60"))
  214. mw.Close()
  215. req, err := http.NewRequest("POST", "/upload/", &b)
  216. req.Header.Set("Content-Type", mw.FormDataContentType())
  217. req.Header.Set("Accept", "application/json")
  218. if err != nil {
  219. t.Fatal(err)
  220. }
  221. goji.DefaultMux.ServeHTTP(w, req)
  222. if w.Code != 200 {
  223. t.Log(w.Body.String())
  224. t.Fatalf("Status code is not 200, but %d", w.Code)
  225. }
  226. var myjson RespOkJSON
  227. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  228. if err != nil {
  229. t.Fatal(err)
  230. }
  231. if myjson.Filename != filename {
  232. t.Fatalf("Filename is not '%s' but '%s' ", filename, myjson.Filename)
  233. }
  234. myExp, err := strconv.ParseInt(myjson.Expiry, 10, 64)
  235. if err != nil {
  236. t.Fatal(err)
  237. }
  238. curTime := time.Now().Unix()
  239. if myExp < curTime {
  240. t.Fatalf("File expiry (%d) is smaller than current time (%d)", myExp, curTime)
  241. }
  242. if myjson.Size != "12" {
  243. t.Fatalf("File size was not 12 but %s", myjson.Size)
  244. }
  245. }
  246. func TestPostRandomizeJSONUpload(t *testing.T) {
  247. w := httptest.NewRecorder()
  248. filename := generateBarename() + ".txt"
  249. var b bytes.Buffer
  250. mw := multipart.NewWriter(&b)
  251. fw, err := mw.CreateFormFile("file", filename)
  252. if err != nil {
  253. t.Fatal(err)
  254. }
  255. fw.Write([]byte("File content"))
  256. rnd, err := mw.CreateFormField("randomize")
  257. if err != nil {
  258. t.Fatal(err)
  259. }
  260. rnd.Write([]byte("true"))
  261. mw.Close()
  262. req, err := http.NewRequest("POST", "/upload/", &b)
  263. req.Header.Set("Content-Type", mw.FormDataContentType())
  264. req.Header.Set("Accept", "application/json")
  265. if err != nil {
  266. t.Fatal(err)
  267. }
  268. goji.DefaultMux.ServeHTTP(w, req)
  269. if w.Code != 200 {
  270. t.Log(w.Body.String())
  271. t.Fatalf("Status code is not 200, but %d", w.Code)
  272. }
  273. var myjson RespOkJSON
  274. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  275. if err != nil {
  276. t.Fatal(err)
  277. }
  278. if myjson.Filename == filename {
  279. t.Fatalf("Filename (%s) is not random (%s)", filename, myjson.Filename)
  280. }
  281. if myjson.Size != "12" {
  282. t.Fatalf("File size was not 12 but %s", myjson.Size)
  283. }
  284. }
  285. func TestPostEmptyUpload(t *testing.T) {
  286. w := httptest.NewRecorder()
  287. filename := generateBarename() + ".txt"
  288. var b bytes.Buffer
  289. mw := multipart.NewWriter(&b)
  290. fw, err := mw.CreateFormFile("file", filename)
  291. if err != nil {
  292. t.Fatal(err)
  293. }
  294. fw.Write([]byte(""))
  295. mw.Close()
  296. req, err := http.NewRequest("POST", "/upload/", &b)
  297. req.Header.Set("Content-Type", mw.FormDataContentType())
  298. if err != nil {
  299. t.Fatal(err)
  300. }
  301. goji.DefaultMux.ServeHTTP(w, req)
  302. if w.Code != 500 {
  303. t.Log(w.Body.String())
  304. t.Fatalf("Status code is not 500, but %d", w.Code)
  305. }
  306. if !strings.Contains(w.Body.String(), "Empty file") {
  307. t.Fatal("Response did not contain 'Empty file'")
  308. }
  309. }
  310. func TestPostEmptyJSONUpload(t *testing.T) {
  311. w := httptest.NewRecorder()
  312. filename := generateBarename() + ".txt"
  313. var b bytes.Buffer
  314. mw := multipart.NewWriter(&b)
  315. fw, err := mw.CreateFormFile("file", filename)
  316. if err != nil {
  317. t.Fatal(err)
  318. }
  319. fw.Write([]byte(""))
  320. mw.Close()
  321. req, err := http.NewRequest("POST", "/upload/", &b)
  322. req.Header.Set("Content-Type", mw.FormDataContentType())
  323. req.Header.Set("Accept", "application/json")
  324. if err != nil {
  325. t.Fatal(err)
  326. }
  327. goji.DefaultMux.ServeHTTP(w, req)
  328. if w.Code != 500 {
  329. t.Log(w.Body.String())
  330. t.Fatalf("Status code is not 500, but %d", w.Code)
  331. }
  332. var myjson RespErrJSON
  333. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  334. if err != nil {
  335. t.Fatal(err)
  336. }
  337. if myjson.Error != "Could not upload file: Empty file" {
  338. t.Fatal("Json 'error' was not 'Empty file' but " + myjson.Error)
  339. }
  340. }
  341. func TestPutUpload(t *testing.T) {
  342. w := httptest.NewRecorder()
  343. filename := generateBarename() + ".ext"
  344. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader("File content"))
  345. if err != nil {
  346. t.Fatal(err)
  347. }
  348. goji.DefaultMux.ServeHTTP(w, req)
  349. if w.Body.String() != Config.siteURL+filename {
  350. t.Fatal("Response was not expected URL")
  351. }
  352. }
  353. func TestPutRandomizedUpload(t *testing.T) {
  354. w := httptest.NewRecorder()
  355. filename := generateBarename() + ".ext"
  356. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader("File content"))
  357. if err != nil {
  358. t.Fatal(err)
  359. }
  360. req.Header.Set("Linx-Randomize", "yes")
  361. goji.DefaultMux.ServeHTTP(w, req)
  362. if w.Body.String() == Config.siteURL+filename {
  363. t.Fatal("Filename was not random")
  364. }
  365. }
  366. func TestPutNoExtensionUpload(t *testing.T) {
  367. w := httptest.NewRecorder()
  368. filename := generateBarename()
  369. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader("File content"))
  370. if err != nil {
  371. t.Fatal(err)
  372. }
  373. req.Header.Set("Linx-Randomize", "yes")
  374. goji.DefaultMux.ServeHTTP(w, req)
  375. if w.Body.String() == Config.siteURL+filename {
  376. t.Fatal("Filename was not random")
  377. }
  378. }
  379. func TestPutEmptyUpload(t *testing.T) {
  380. w := httptest.NewRecorder()
  381. filename := generateBarename() + ".ext"
  382. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader(""))
  383. if err != nil {
  384. t.Fatal(err)
  385. }
  386. req.Header.Set("Linx-Randomize", "yes")
  387. goji.DefaultMux.ServeHTTP(w, req)
  388. if !strings.Contains(w.Body.String(), "Empty file") {
  389. t.Fatal("Response doesn't contain'Empty file'")
  390. }
  391. }
  392. func TestPutJSONUpload(t *testing.T) {
  393. var myjson RespOkJSON
  394. w := httptest.NewRecorder()
  395. filename := generateBarename() + ".ext"
  396. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader("File content"))
  397. if err != nil {
  398. t.Fatal(err)
  399. }
  400. req.Header.Set("Accept", "application/json")
  401. goji.DefaultMux.ServeHTTP(w, req)
  402. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  403. if err != nil {
  404. t.Fatal(err)
  405. }
  406. if myjson.Filename != filename {
  407. t.Fatal("Filename was not provided one but " + myjson.Filename)
  408. }
  409. }
  410. func TestPutRandomizedJSONUpload(t *testing.T) {
  411. var myjson RespOkJSON
  412. w := httptest.NewRecorder()
  413. filename := generateBarename() + ".ext"
  414. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader("File content"))
  415. if err != nil {
  416. t.Fatal(err)
  417. }
  418. req.Header.Set("Accept", "application/json")
  419. req.Header.Set("Linx-Randomize", "yes")
  420. goji.DefaultMux.ServeHTTP(w, req)
  421. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  422. if err != nil {
  423. t.Fatal(err)
  424. }
  425. if myjson.Filename == filename {
  426. t.Fatal("Filename was not random ")
  427. }
  428. }
  429. func TestPutExpireJSONUpload(t *testing.T) {
  430. var myjson RespOkJSON
  431. w := httptest.NewRecorder()
  432. filename := generateBarename() + ".ext"
  433. req, err := http.NewRequest("PUT", "/upload/"+filename, strings.NewReader("File content"))
  434. if err != nil {
  435. t.Fatal(err)
  436. }
  437. req.Header.Set("Accept", "application/json")
  438. req.Header.Set("Linx-Expiry", "600")
  439. goji.DefaultMux.ServeHTTP(w, req)
  440. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  441. if err != nil {
  442. t.Fatal(err)
  443. }
  444. expiry, err := strconv.Atoi(myjson.Expiry)
  445. if err != nil {
  446. t.Fatal("Expiry was not an integer")
  447. }
  448. if expiry < 1 {
  449. t.Fatal("Expiry was not set")
  450. }
  451. }
  452. func TestPutAndDelete(t *testing.T) {
  453. var myjson RespOkJSON
  454. w := httptest.NewRecorder()
  455. req, err := http.NewRequest("PUT", "/upload", strings.NewReader("File content"))
  456. if err != nil {
  457. t.Fatal(err)
  458. }
  459. req.Header.Set("Accept", "application/json")
  460. goji.DefaultMux.ServeHTTP(w, req)
  461. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  462. if err != nil {
  463. t.Fatal(err)
  464. }
  465. // Delete it
  466. w = httptest.NewRecorder()
  467. req, err = http.NewRequest("DELETE", "/"+myjson.Filename, nil)
  468. req.Header.Set("Linx-Delete-Key", myjson.Delete_Key)
  469. goji.DefaultMux.ServeHTTP(w, req)
  470. if w.Code != 200 {
  471. t.Fatal("Status code was not 200, but " + strconv.Itoa(w.Code))
  472. }
  473. // Make sure it's actually gone
  474. w = httptest.NewRecorder()
  475. req, err = http.NewRequest("GET", "/"+myjson.Filename, nil)
  476. goji.DefaultMux.ServeHTTP(w, req)
  477. if w.Code != 404 {
  478. t.Fatal("Status code was not 404, but " + strconv.Itoa(w.Code))
  479. }
  480. // Make sure torrent is also gone
  481. w = httptest.NewRecorder()
  482. req, err = http.NewRequest("GET", "/"+myjson.Filename+"/torrent", nil)
  483. goji.DefaultMux.ServeHTTP(w, req)
  484. if w.Code != 404 {
  485. t.Fatal("Status code was not 404, but " + strconv.Itoa(w.Code))
  486. }
  487. }
  488. func TestPutAndSpecificDelete(t *testing.T) {
  489. var myjson RespOkJSON
  490. w := httptest.NewRecorder()
  491. req, err := http.NewRequest("PUT", "/upload", strings.NewReader("File content"))
  492. if err != nil {
  493. t.Fatal(err)
  494. }
  495. req.Header.Set("Accept", "application/json")
  496. req.Header.Set("Linx-Delete-Key", "supersecret")
  497. goji.DefaultMux.ServeHTTP(w, req)
  498. err = json.Unmarshal([]byte(w.Body.String()), &myjson)
  499. if err != nil {
  500. t.Fatal(err)
  501. }
  502. // Delete it
  503. w = httptest.NewRecorder()
  504. req, err = http.NewRequest("DELETE", "/"+myjson.Filename, nil)
  505. req.Header.Set("Linx-Delete-Key", "supersecret")
  506. goji.DefaultMux.ServeHTTP(w, req)
  507. if w.Code != 200 {
  508. t.Fatal("Status code was not 200, but " + strconv.Itoa(w.Code))
  509. }
  510. // Make sure it's actually gone
  511. w = httptest.NewRecorder()
  512. req, err = http.NewRequest("GET", "/"+myjson.Filename, nil)
  513. goji.DefaultMux.ServeHTTP(w, req)
  514. if w.Code != 404 {
  515. t.Fatal("Status code was not 404, but " + strconv.Itoa(w.Code))
  516. }
  517. // Make sure torrent is gone too
  518. w = httptest.NewRecorder()
  519. req, err = http.NewRequest("GET", "/"+myjson.Filename+"/torrent", nil)
  520. goji.DefaultMux.ServeHTTP(w, req)
  521. if w.Code != 404 {
  522. t.Fatal("Status code was not 404, but " + strconv.Itoa(w.Code))
  523. }
  524. }
  525. func TestShutdown(t *testing.T) {
  526. os.RemoveAll(Config.filesDir)
  527. os.RemoveAll(Config.metaDir)
  528. }