package Api import ( "bytes" "encoding/json" "errors" "fmt" "io" "io/ioutil" "log" "mime/multipart" "net/http" "net/http/httptest" "os" "path" "path/filepath" "runtime" "strconv" "testing" "git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Database" "git.tovijaeschke.xyz/tovi/SuddenImpactRecords/Models" "gorm.io/gorm" "github.com/gorilla/mux" ) func init() { // Fix working directory for tests _, filename, _, _ := runtime.Caller(0) dir := path.Join(path.Dir(filename), "..") err := os.Chdir(dir) if err != nil { panic(err) } log.SetOutput(ioutil.Discard) Database.Init() r = mux.NewRouter() } func get(url string) (resp *http.Response, err error) { for i := 0; i < 5; i++ { resp, err = http.Get(url) if err == nil { return resp, err } } return resp, err } // Image generates a *os.File with a random image using the loremflickr.com service func fakeImage(width, height int, categories []string, prefix string, categoriesStrict bool) *os.File { url := "https://loremflickr.com" switch prefix { case "g": url += "/g" case "p": url += "/p" case "red": url += "/red" case "green": url += "/green" case "blue": url += "/blue" } url += string('/') + strconv.Itoa(width) + string('/') + strconv.Itoa(height) if len(categories) > 0 { url += string('/') for _, category := range categories { url += category + string(',') } if categoriesStrict { url += "/all" } } resp, err := get(url) defer resp.Body.Close() if err != nil { panic(err) } f, err := ioutil.TempFile(os.TempDir(), "loremflickr-img-*.jpg") if err != nil { panic(err) } io.Copy(f, resp.Body) err = f.Close() if err != nil { panic(err) } return f } func Test_createPostImages(t *testing.T) { t.Log("Testing createPostImages...") r.HandleFunc("/post/{postID}/image", createPostImage).Methods("POST") ts := httptest.NewServer(r) defer ts.Close() postData := Models.Post{ Title: "Test post", Content: "Test content", FrontPage: true, Order: 1, PostLinks: []Models.PostLink{ { Type: "Facebook", Link: "http://facebook.com/", }, }, } err := Database.CreatePost(&postData) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } image := fakeImage(100, 100, []string{}, "", false) image, err = os.Open(image.Name()) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } body := &bytes.Buffer{} writer := multipart.NewWriter(body) part, err := writer.CreateFormFile("files", filepath.Base(image.Name())) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } io.Copy(part, image) writer.Close() request, err := http.NewRequest( "POST", fmt.Sprintf( "%s/post/%s/image", ts.URL, postData.ID, ), body, ) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } request.Header.Add("Content-Type", writer.FormDataContentType()) client := &http.Client{} res, err := client.Do(request) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) } defer res.Body.Close() updatePostData := new(Models.Post) err = json.NewDecoder(res.Body).Decode(updatePostData) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } defer Database.DB. Session(&gorm.Session{FullSaveAssociations: true}). Unscoped(). Select("PostLinks", "PostImages"). Delete(&postData) if len(updatePostData.PostImages) != 1 { t.Errorf("Expected len(updatePostData.PostImages) == 1, recieved %d", len(updatePostData.PostImages)) } for _, f := range updatePostData.PostImages { if _, err := os.Stat("./" + f.Filepath); errors.Is(err, os.ErrNotExist) { t.Errorf( "File ./%s does not exist", f.Filepath, ) } else { os.Remove("./" + f.Filepath) } } } func Test_deletePostImages(t *testing.T) { t.Log("Testing createPostImages...") r.HandleFunc("/post/{postID}/image/{imageID}", deletePostImage).Methods("DELETE") ts := httptest.NewServer(r) defer ts.Close() image := fakeImage(100, 100, []string{}, "", false) image, err := os.Open(image.Name()) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } defer image.Close() postData := Models.Post{ Title: "Test post", Content: "Test content", FrontPage: true, Order: 1, PostLinks: []Models.PostLink{ { Type: "Facebook", Link: "http://facebook.com/", }, }, PostImages: []Models.PostImage{ { Filepath: image.Name(), }, }, } err = Database.CreatePost(&postData) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } defer Database.DB. Session(&gorm.Session{FullSaveAssociations: true}). Unscoped(). Select("PostLinks", "PostImages"). Delete(&postData) req, err := http.NewRequest("DELETE", fmt.Sprintf( "%s/post/%s/image/%s", ts.URL, postData.ID, postData.PostImages[0].ID, ), nil) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) } res, err := http.DefaultClient.Do(req) if err != nil { t.Errorf("Expected nil, recieved %s", err.Error()) return } defer res.Body.Close() if res.StatusCode != http.StatusOK { t.Errorf("Expected %d, recieved %d", http.StatusOK, res.StatusCode) } }