Skip to content

Commit

Permalink
Chore: Add unit tests (#50)
Browse files Browse the repository at this point in the history
* feat: WIP - added router.go ginkgo unit tests

* feat: WIP - added handlers.go unit tests using mocks

* feat: WIP - added handlers.go unit tests using mocks

* feat:  added handlers.go unit tests using mocks

* chore: Updated coverage badge.

---------

Co-authored-by: Finsen Varghese <[email protected]>
Co-authored-by: GitHub Action <[email protected]>
  • Loading branch information
3 people authored Jan 24, 2024
1 parent 5ea7575 commit a567e6f
Show file tree
Hide file tree
Showing 8 changed files with 152 additions and 25 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*.dll
*.so
*.dylib
*.idea

# Test binary, built with `go test -c`
*.test
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/Guidewire/fern-reporter/badge)](https://securityscorecards.dev/viewer/?uri=github.com/Guidewire/fern-reporter)
![Coverage](https://img.shields.io/badge/Coverage-60.0%25-yellow)
![Coverage](https://img.shields.io/badge/Coverage-23.0%25-red)

![Fern](https://github.com/guidewire/fern-reporter/raw/main/docs/images/logo-no-background.png)

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/guidewire/fern-reporter
go 1.21

require (
github.com/DATA-DOG/go-sqlmock v1.5.2
github.com/gin-contrib/cors v1.4.0
github.com/gin-gonic/gin v1.9.1
github.com/golang-migrate/migrate/v4 v4.16.2
Expand Down
3 changes: 3 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
Expand Down Expand Up @@ -97,6 +99,7 @@ github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
Expand Down
39 changes: 23 additions & 16 deletions pkg/api/handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ import (

"github.com/guidewire/fern-reporter/pkg/models"

"github.com/guidewire/fern-reporter/pkg/db"

"github.com/gin-gonic/gin"
"gorm.io/gorm"
)

func CreateTestRun(c *gin.Context) {
type Handler struct {
db *gorm.DB
}

func NewHandler(db *gorm.DB) *Handler {
return &Handler{db: db}
}

func (h *Handler) CreateTestRun(c *gin.Context) {
var testRun models.TestRun

if err := c.ShouldBindJSON(&testRun); err != nil {
Expand All @@ -24,7 +30,7 @@ func CreateTestRun(c *gin.Context) {
return // Stop further processing if there is a binding error
}

gdb := db.GetDb()
gdb := h.db
isNewRecord := testRun.ID == 0

// If it's not a new record, try to find it first
Expand Down Expand Up @@ -83,24 +89,25 @@ func ProcessTags(db *gorm.DB, testRun *models.TestRun) error {
return nil
}

func GetTestRunAll(c *gin.Context) {
func (h *Handler) GetTestRunAll(c *gin.Context) {
var testRuns []models.TestRun
db.GetDb().Find(&testRuns)
h.db.Find(&testRuns)
c.JSON(http.StatusOK, testRuns)
}

func GetTestRunByID(c *gin.Context) {
func (h *Handler) GetTestRunByID(c *gin.Context) {
var testRun models.TestRun
id := c.Param("id")
db.GetDb().Where("id = ?", id).First(&testRun)
h.db.Where("id = ?", id).First(&testRun)
c.JSON(http.StatusOK, testRun)

}

func UpdateTestRun(c *gin.Context) {
func (h *Handler) UpdateTestRun(c *gin.Context) {
var testRun models.TestRun
id := c.Param("id")

db := db.GetDb()
db := h.db
if err := db.Where("id = ?", id).First(&testRun).Error; err != nil {
c.AbortWithStatus(http.StatusNotFound)
return
Expand All @@ -114,7 +121,7 @@ func UpdateTestRun(c *gin.Context) {
c.JSON(http.StatusOK, &testRun)
}

func DeleteTestRun(c *gin.Context) {
func (h *Handler) DeleteTestRun(c *gin.Context) {
var testRun models.TestRun
id := c.Param("id")
if testRunID, err := strconv.Atoi(id); err != nil {
Expand All @@ -124,7 +131,7 @@ func DeleteTestRun(c *gin.Context) {
testRun.ID = uint64(testRunID)
}

result := db.GetDb().Delete(&testRun)
result := h.db.Delete(&testRun)
if result.Error != nil {
// If there was an error during the delete operation
c.JSON(http.StatusInternalServerError, gin.H{"error": "error deleting test run"})
Expand All @@ -138,18 +145,18 @@ func DeleteTestRun(c *gin.Context) {
c.JSON(http.StatusOK, &testRun)
}

func ReportTestRunAll(c *gin.Context) {
func (h *Handler) ReportTestRunAll(c *gin.Context) {
var testRuns []models.TestRun
db.GetDb().Preload("SuiteRuns.SpecRuns").Find(&testRuns)
h.db.Preload("SuiteRuns.SpecRuns").Find(&testRuns)
c.HTML(http.StatusOK, "test_runs.html", gin.H{
"testRuns": testRuns,
})
}

func ReportTestRunById(c *gin.Context) {
func (h *Handler) ReportTestRunById(c *gin.Context) {
var testRun models.TestRun
id := c.Param("id")
db.GetDb().Preload("SuiteRuns.SpecRuns").Where("id = ?", id).First(&testRun)
h.db.Preload("SuiteRuns.SpecRuns").Where("id = ?", id).First(&testRun)
c.HTML(http.StatusOK, "test_runs.html", gin.H{
"testRuns": []models.TestRun{testRun},
})
Expand Down
13 changes: 13 additions & 0 deletions pkg/api/handlers/handlers_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package handlers_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestHandlers(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Handlers Suite")
}
99 changes: 99 additions & 0 deletions pkg/api/handlers/handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package handlers_test

import (
"database/sql"
"encoding/json"
"net/http/httptest"

"github.com/DATA-DOG/go-sqlmock"
"github.com/gin-gonic/gin"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"gorm.io/driver/postgres"
"gorm.io/gorm"

"github.com/guidewire/fern-reporter/pkg/api/handlers"
"github.com/guidewire/fern-reporter/pkg/models"
)

var (
db *sql.DB
gormDb *gorm.DB
mock sqlmock.Sqlmock
)

var _ = BeforeSuite(func() {
db, mock, _ = sqlmock.New()

dialector := postgres.New(postgres.Config{
DSN: "sqlmock_db_0",
DriverName: "postgres",
Conn: db,
PreferSimpleProtocol: true,
})
gormDb, _ = gorm.Open(dialector, &gorm.Config{})

})

var _ = AfterSuite(func() {
db.Close()
})

var _ = Describe("Handlers", func() {
Context("when GetTestRunAll handleer is invoked", func() {
It("should query db to fetch all records", func() {

rows := sqlmock.NewRows([]string{"ID", "TestProjectName"}).
AddRow(1, "project 1").
AddRow(2, "project 2")

mock.ExpectQuery("SELECT (.+) FROM \"test_runs\"").
WithoutArgs().
WillReturnRows(rows)
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
handler := handlers.NewHandler(gormDb)

handler.GetTestRunAll(c)

Expect(w.Code).To(Equal(200))

var testRuns []models.TestRun
if err := json.NewDecoder(w.Body).Decode(&testRuns); err != nil {
Fail(err.Error())
}
Expect(len(testRuns)).To(Equal(2))
Expect(testRuns[0].TestProjectName).To(Equal("project 1"))
Expect(testRuns[1].TestProjectName).To(Equal("project 2"))
})
})

Context("When GetTestRunByID handler is invoked", func() {
It("should query DB with where clause filtering by id", func() {

rows := sqlmock.NewRows([]string{"ID", "TestProjectName"}).
AddRow(123, "project 123")

mock.ExpectQuery("SELECT (.+) FROM \"test_runs\" WHERE id = \\$1").
WithArgs("123").
WillReturnRows(rows)

w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)

c.Params = append(c.Params, gin.Param{Key: "id", Value: "123"})
handler := handlers.NewHandler(gormDb)
handler.GetTestRunByID(c)

Expect(w.Code).To(Equal(200))

var testRun models.TestRun

if err := json.NewDecoder(w.Body).Decode(&testRun); err != nil {
Fail(err.Error())
}
Expect(int(testRun.ID)).To(Equal(123))
Expect(testRun.TestProjectName).To(Equal("project 123"))
})
})
})
19 changes: 11 additions & 8 deletions pkg/api/routers/routers.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@ package routers

import (
"github.com/guidewire/fern-reporter/pkg/api/handlers"
"github.com/guidewire/fern-reporter/pkg/db"

"github.com/gin-gonic/gin"
)

func RegisterRouters(router *gin.Engine) {
// router.GET("/", handlers.Home)
handler := handlers.NewHandler(db.GetDb())

api := router.Group("/api")
{
testRun := api.Group("/testrun")
testRun.GET("/", handlers.GetTestRunAll)
testRun.GET("/:id", handlers.GetTestRunByID)
testRun.POST("/", handlers.CreateTestRun)
testRun.PUT("/:id", handlers.UpdateTestRun)
testRun.DELETE("/:id", handlers.DeleteTestRun)
testRun := api.Group("/testrun/")
testRun.GET("/", handler.GetTestRunAll)
testRun.GET("/:id", handler.GetTestRunByID)
testRun.POST("/", handler.CreateTestRun)
testRun.PUT("/:id", handler.UpdateTestRun)
testRun.DELETE("/:id", handler.DeleteTestRun)
}
reports := router.Group("/reports/testruns")
{
testRunReport := reports.GET("/", handlers.ReportTestRunAll)
testRunReport.GET("/:id", handlers.ReportTestRunById)
testRunReport := reports.GET("/", handler.ReportTestRunAll)
testRunReport.GET("/:id", handler.ReportTestRunById)
}
}

0 comments on commit a567e6f

Please sign in to comment.