From 802c27d0637d7da72d8d3c51123750a4a92748f3 Mon Sep 17 00:00:00 2001 From: hhertout Date: Mon, 18 Dec 2023 19:15:00 +0100 Subject: [PATCH 1/3] refactor: dockerfile --- dev.dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev.dockerfile b/dev.dockerfile index 9bfedb4..f966311 100644 --- a/dev.dockerfile +++ b/dev.dockerfile @@ -14,7 +14,7 @@ WORKDIR /app COPY . . RUN mkdir data -RUN go mod download +RUN go mod download CMD ["make", "watch"] \ No newline at end of file From 85ad9e82455991e4510aa0581e98d6c2fefd779f Mon Sep 17 00:00:00 2001 From: hhertout Date: Tue, 19 Dec 2023 17:11:48 +0100 Subject: [PATCH 2/3] refactor: update for test --- cmd/api/main.go | 6 +++++- cmd/database/migration.go | 8 +++++--- src/controllers/controller.go | 2 +- src/repository/mail.repository.go | 24 ++++++++++++++++-------- src/repository/repository.go | 22 ++++++++++++++-------- 5 files changed, 41 insertions(+), 21 deletions(-) diff --git a/cmd/api/main.go b/cmd/api/main.go index 6b898e3..97aafa9 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -19,14 +19,18 @@ func main() { } db, err := database.Connect() - migration := database.NewMigration(db) if err != nil { log.Println("Failed to connect to db") } + migration := database.NewMigration(db, "") if err = migration.Migrate(); err != nil { fmt.Printf("Failed to migrate db: %s", err) } + if err = db.Close(); err != nil { + log.Println("Failed to close db connection after migration") + } + r := router.Serve() log.Printf("📡 Server start on port %s \n", os.Getenv("PORT")) if err := r.Run(); err != nil { diff --git a/cmd/database/migration.go b/cmd/database/migration.go index acbe939..b9fddef 100644 --- a/cmd/database/migration.go +++ b/cmd/database/migration.go @@ -8,12 +8,14 @@ import ( ) type Migration struct { - dbPool *sql.DB + dbPool *sql.DB + basePath string } -func NewMigration(db *sql.DB) *Migration { +func NewMigration(db *sql.DB, basePath string) *Migration { return &Migration{ db, + basePath, } } @@ -26,7 +28,7 @@ func (m Migration) Migrate() error { func (m Migration) migrateFromFile(filename string) error { workingDir, _ := os.Getwd() - fileOpen, err := os.Open(workingDir + "/cmd/database/migrations/" + filename) + fileOpen, err := os.Open(workingDir + m.basePath + "/cmd/database/migrations/" + filename) if err != nil { return err } diff --git a/src/controllers/controller.go b/src/controllers/controller.go index 0e6dd3e..b6150dd 100644 --- a/src/controllers/controller.go +++ b/src/controllers/controller.go @@ -20,7 +20,7 @@ type MailRequest[T interface{}] struct { } func NewApiController() *ApiController { - newRepository, err := repository.NewRepository() + newRepository, err := repository.NewRepository(nil) if err != nil { log.Printf("Repositority initialisation failed : %s", err) } diff --git a/src/repository/mail.repository.go b/src/repository/mail.repository.go index b67db0a..6c42a9d 100644 --- a/src/repository/mail.repository.go +++ b/src/repository/mail.repository.go @@ -1,13 +1,13 @@ package repository type MailQuery struct { - ID int `db:"_id"` - Date string `db:"date"` - To string `db:"to"` - Subject string `db:"subject"` - Sent bool `db:"sent"` - Error string `db:"error"` - Viewed string `db:"viewed"` + ID int `db:"_id"` + Date string `db:"date"` + To string `db:"to"` + Subject string `db:"subject"` + Sent bool `db:"sent"` + Error *string `db:"error"` + Viewed string `db:"viewed"` } type MailSaveWithoutError struct { @@ -70,9 +70,17 @@ func (r Repository) ListMail() ([]MailQuery, error) { } func (r Repository) convertToToString(args []string) string { + if len(args) == 0 { + return "" + } + + if len(args) == 1 { + return args[0] + } + res := "" for _, dest := range args { - res += dest + res = res + dest + ";" } return res } diff --git a/src/repository/repository.go b/src/repository/repository.go index 45eb7ad..f3bc457 100644 --- a/src/repository/repository.go +++ b/src/repository/repository.go @@ -9,13 +9,19 @@ type Repository struct { dbPool *sql.DB } -func NewRepository() (*Repository, error) { - dbPool, err := database.Connect() - if err != nil { - return nil, err - } +func NewRepository(customSource *sql.DB) (*Repository, error) { + if customSource != nil { + return &Repository{ + customSource, + }, nil + } else { + dbPool, err := database.Connect() + if err != nil { + return nil, err + } - return &Repository{ - dbPool, - }, nil + return &Repository{ + dbPool, + }, nil + } } From 4b691c174052f9b01f400439f78fcc7f896f11c3 Mon Sep 17 00:00:00 2001 From: hhertout Date: Tue, 19 Dec 2023 17:11:59 +0100 Subject: [PATCH 3/3] test: adding tests --- .github/workflows/go.yml | 2 +- Makefile | 2 +- tests/{ => e2e}/main_test.go | 2 +- tests/integration/controller_test.go | 19 +++ tests/integration/mailRepository_test.go | 151 ++++++++++++++++++ tests/integration/repository_test.go | 49 ++++++ .../request_test.go} | 2 +- tests/specs/database_test.go | 29 ++++ 8 files changed, 252 insertions(+), 4 deletions(-) rename tests/{ => e2e}/main_test.go (95%) create mode 100644 tests/integration/controller_test.go create mode 100644 tests/integration/mailRepository_test.go create mode 100644 tests/integration/repository_test.go rename tests/{mailing_test.go => integration/request_test.go} (94%) create mode 100644 tests/specs/database_test.go diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index b8b5d65..8b40921 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -17,7 +17,7 @@ jobs: with: go-version: 1.20.3 - name: Tests - run: go test ./tests + run: go test ./tests/... build: runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index acd7026..a72ef5b 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ dc-down: # Test the application test: @echo "Testing..." - @go test ./tests -v + @go test ./tests/... -v # Clean the binary clean: diff --git a/tests/main_test.go b/tests/e2e/main_test.go similarity index 95% rename from tests/main_test.go rename to tests/e2e/main_test.go index 711424d..3d697ce 100644 --- a/tests/main_test.go +++ b/tests/e2e/main_test.go @@ -1,4 +1,4 @@ -package tests_test +package e2e_test import ( "mailer_ms/src/router" diff --git a/tests/integration/controller_test.go b/tests/integration/controller_test.go new file mode 100644 index 0000000..d416862 --- /dev/null +++ b/tests/integration/controller_test.go @@ -0,0 +1,19 @@ +package integration_test + +import ( + "mailer_ms/src/controllers" + "os" + "testing" +) + +func TestNewController(t *testing.T) { + err := os.Setenv("DB_URL", "../../data/mailerTest.db") + if err != nil { + t.Error("Failed to set db env") + } + + a := controllers.NewApiController() + if a == nil { + t.Error("Repository is null") + } +} diff --git a/tests/integration/mailRepository_test.go b/tests/integration/mailRepository_test.go new file mode 100644 index 0000000..176714e --- /dev/null +++ b/tests/integration/mailRepository_test.go @@ -0,0 +1,151 @@ +package integration_test + +import ( + "errors" + "mailer_ms/src/repository" + "os" + "testing" +) + +func TestWithoutError(t *testing.T) { + // Setup + err := os.Setenv("DB_URL", "./data/mailer_test.db") + + if err != nil { + t.Error("Failed to set db env") + } + + dbPool, err := connect() + if err != nil { + t.Error("Failed to connect to db") + } + + r, err := repository.NewRepository(dbPool) + if err != nil { + t.Error("repository instantiation failed") + } + if r == nil { + t.Error("Repository is null") + } + + // testing method + to := []string{"test@example.com", "another@example.com"} + subject := "Test subject" + + err = r.SaveWithoutError(to, subject) + if err != nil { + t.Errorf("SaveWithoutError failed: %s", err) + } +} + +func TestSaveWithError(t *testing.T) { + // Setup + err := os.Setenv("DB_URL", "./data/mailer_test.db") + + if err != nil { + t.Error("Failed to set db env") + } + + dbPool, err := connect() + if err != nil { + t.Error("Failed to connect to db") + } + + r, err := repository.NewRepository(dbPool) + if err != nil { + t.Error("repository instantiation failed") + } + if r == nil { + t.Error("Repository is null") + } + + // testing method + to := []string{"test@example.com", "another@example.com"} + subject := "Test subject" + + err = r.SaveWithError(to, subject, errors.New("failed")) + if err != nil { + t.Errorf("SaveWithoutError failed: %s", err) + } +} + +func TestListMail(t *testing.T) { + // Setup + if err := os.Setenv("DB_URL", "./data/mailer_test.db"); err != nil { + t.Error("Failed to set db env") + } + + dbPool, err := connect() + if err != nil { + t.Error("Failed to connect to db") + } + + if _, err = dbPool.Exec(`DELETE FROM "mail"`); err != nil { + t.Error("Failed to reset db") + } + + r, err := repository.NewRepository(dbPool) + if err != nil { + t.Error("repository instantiation failed") + } + if r == nil { + t.Error("Repository is null") + } + + // >Insert some data with the 2 methods + toWithoutError := []string{"test@example.com", "another@example.com"} + subjectWithoutError := "Test subject without error" + err = r.SaveWithoutError(toWithoutError, subjectWithoutError) + if err != nil { + t.Errorf("SaveWithoutError failed: %s", err) + } + toWithError := []string{"error@example.com", "fail@example.com"} + subjectWithError := "Test subject with error" + + err = r.SaveWithError(toWithError, subjectWithError, errors.New("error")) + if err != nil { + t.Errorf("SaveWithError failed: %s", err) + } + + // Test ListMail > must retrieve data inserted before + mails, err := r.ListMail() + if err != nil { + t.Errorf("ListMail failed: %s", err) + } + + if len(mails) < 2 { + t.Error("Expected 2 min mails, got", len(mails)) + } + + mailWithErrIsContained := false + mailWithoutErrIsContained := false + + for _, mail := range mails { + if mail.Subject == "Test subject with error" { + mailWithErrIsContained = true + + if mail.To != "error@example.com;fail@example.com;" { + t.Errorf(" Expect error@example.com;fail@example.com;, got %v", mail.To) + } + + if mail.Sent != false { + t.Errorf("false, got %v", mail.Sent) + } + + } else if mail.Subject == "Test subject without error" { + mailWithoutErrIsContained = true + + if mail.To != "test@example.com;another@example.com;" { + t.Errorf(" Expect test@example.com;another@example.com;, got %v", mail.To) + } + + if mail.Sent != true { + t.Errorf("true, got %v", mail.Sent) + } + } + } + + if !mailWithErrIsContained || !mailWithoutErrIsContained { + t.Error("Expected 2 mail inserted") + } +} diff --git a/tests/integration/repository_test.go b/tests/integration/repository_test.go new file mode 100644 index 0000000..194bab9 --- /dev/null +++ b/tests/integration/repository_test.go @@ -0,0 +1,49 @@ +package integration_test + +import ( + "database/sql" + "mailer_ms/cmd/database" + "mailer_ms/src/repository" + "os" + "testing" +) + +func connect() (*sql.DB, error) { + err := os.Setenv("DB_URL", "../../data/mailerTest.db") + if err != nil { + return nil, err + } + + db, errConnect := database.Connect() + if errConnect != nil { + return nil, err + } + + migration := database.NewMigration(db, "/../..") + if err = migration.Migrate(); err != nil { + return nil, err + } + + return db, nil +} + +func TestNewRepository(t *testing.T) { + err := os.Setenv("DB_URL", "./data/mailer_test.db") + + if err != nil { + t.Error("Failed to set db env") + } + + dbPool, err := connect() + if err != nil { + t.Error("Failed to connect to db") + } + + r, err := repository.NewRepository(dbPool) + if err != nil { + t.Error("repository instantiation failed") + } + if r == nil { + t.Error("Repository is null") + } +} diff --git a/tests/mailing_test.go b/tests/integration/request_test.go similarity index 94% rename from tests/mailing_test.go rename to tests/integration/request_test.go index 25d4e41..4cb6f19 100644 --- a/tests/mailing_test.go +++ b/tests/integration/request_test.go @@ -1,4 +1,4 @@ -package tests_test +package integration_test import ( GoMailer "mailer_ms/src/mailer" diff --git a/tests/specs/database_test.go b/tests/specs/database_test.go new file mode 100644 index 0000000..9084b3a --- /dev/null +++ b/tests/specs/database_test.go @@ -0,0 +1,29 @@ +package specs + +import ( + "fmt" + "mailer_ms/cmd/database" + "os" + "testing" +) + +func TestDatabase(t *testing.T) { + err := os.Setenv("DB_URL", "../../data/mailerTest.db") + if err != nil { + fmt.Println(err) + t.Error("Failed to set DB_URL") + } + + db, errConnect := database.Connect() + if errConnect != nil { + fmt.Println("Failed to connect to db") + fmt.Println(err) + t.Error("Failed to connect to db") + } + + migration := database.NewMigration(db, "/../..") + if errMigration := migration.Migrate(); errMigration != nil { + fmt.Println(errMigration) + t.Errorf("Failed to migrate db: %s", errMigration) + } +}