package integration import ( "bytes" "io" "log" "mime/multipart" "os" "path" "path/filepath" "strconv" "testing" "github.com/stretchr/testify/assert" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/models" "code.alt-gnome.ru/aides-infra/aides-repo-api/internal/services/taskservice" ) func createMultipartFileHeader(filePath string) *multipart.FileHeader { // open the file file, err := os.Open(filePath) if err != nil { log.Fatal(err) return nil } defer file.Close() // create a buffer to hold the file in memory var buff bytes.Buffer buffWriter := io.Writer(&buff) // create a new form and create a new file field formWriter := multipart.NewWriter(buffWriter) formPart, err := formWriter.CreateFormFile("file", filepath.Base(file.Name())) if err != nil { log.Println(err) return nil } // copy the content of the file to the form's file field if _, err := io.Copy(formPart, file); err != nil { log.Println(err) return nil } // close the form writer after the copying process is finished // I don't use defer in here to avoid unexpected EOF error formWriter.Close() // transform the bytes buffer into a form reader buffReader := bytes.NewReader(buff.Bytes()) formReader := multipart.NewReader(buffReader, formWriter.Boundary()) // read the form components with max stored memory of 1MB multipartForm, err := formReader.ReadForm(1 << 20) if err != nil { log.Println(err) return nil } // return the multipart file header files, exists := multipartForm.File["file"] if !exists || len(files) == 0 { log.Println("multipart file not exists") return nil } return files[0] } func createTaskUploadInput(task *models.Task, fileName string) *taskservice.TaskUploadInput { filePath := path.Join("./test_rpms/", fileName) fileHeader := createMultipartFileHeader(filePath) return &taskservice.TaskUploadInput{ TaskID: strconv.FormatUint(uint64(task.ID), 10), Files: []*multipart.FileHeader{fileHeader}, } } func TestTaskService_Upload(t *testing.T) { t.Run("Correct upload (new)", func(t *testing.T) { db := prepareDb(t) config := prepareConfig() service := taskservice.New(db, config) os.MkdirAll(config.GetUploadDir(), os.ModePerm) os.MkdirAll(path.Join(config.GetUploadDir(), "repo/Sisyphus"), os.ModePerm) defer os.RemoveAll(config.GetUploadDir()) task := &models.Task{ ALTRepoID: 1, RepoID: 1, Status: models.StatusPending, } task.ID = uint(1) db.Create(task) fileName := "example-foo-1.0.0-alt1.x86_64.rpm" err := service.Upload(createTaskUploadInput( task, fileName, )) assert.NoError(t, err) var updatedTask models.Task db.First(&updatedTask, 1) assert.Equal(t, models.StatusCompleted, updatedTask.Status) var rpmFiles []models.RPMFile db.Find(&rpmFiles) assert.Len(t, rpmFiles, 1) assert.Equal(t, fileName, rpmFiles[0].Filename) }) t.Run("Incorrect upload (too old version)", func(t *testing.T) { db := prepareDb(t) config := prepareConfig() service := taskservice.New(db, config) os.MkdirAll(config.GetUploadDir(), os.ModePerm) os.MkdirAll(path.Join(config.GetUploadDir(), "repo/Sisyphus"), os.ModePerm) defer os.RemoveAll(config.GetUploadDir()) // === gitRepo := &models.GitRepo{ Name: "example-foo", } altRepo := &models.ALTRepo{ Name: "Sisyphus", } db.Debug().Create(&models.GitRepoAltRepoTask{ Repo: gitRepo, ALTRepo: altRepo, CurrentTask: &models.Task{ Status: models.StatusCompleted, Files: []models.RPMFile{ { Name: "example-foo", Version: "1.0.0", Release: "2", Epoch: 0, }, }, }, }) task := &models.Task{ Repo: gitRepo, ALTRepo: *altRepo, Status: models.StatusPending, } db.Create(task) // === err := service.Upload(createTaskUploadInput( task, "example-foo-1.0.0-alt1.x86_64.rpm", )) var tooOldErr *taskservice.TooOldError assert.ErrorAs(t, err, &tooOldErr) assert.Equal(t, "example-foo is too old!", tooOldErr.Error()) }) }