diff --git a/controllers/about_test.go b/controllers/about_test.go new file mode 100644 index 0000000..958d5c1 --- /dev/null +++ b/controllers/about_test.go @@ -0,0 +1,17 @@ +package controllers + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestAbout_Get(t *testing.T) { + resp := GetRequest(t, "about") + assert.Equal(t, http.StatusOK, resp.StatusCode) + doc := GetGoqueryDoc(t, resp) + h1 := doc.Find("h1.title") + assert.Len(t, h1.Nodes, 1) + assert.Equal(t, "About", h1.Text()) +} diff --git a/controllers/controller.go b/controllers/controller.go index 1355470..cdf3f15 100644 --- a/controllers/controller.go +++ b/controllers/controller.go @@ -5,6 +5,9 @@ import ( "fmt" "html/template" "net/http" + "path" + "path/filepath" + "runtime" "sync" "goweb/config" @@ -25,6 +28,8 @@ var ( // Template function map funcMap = funcmap.GetFuncMap() + + templatePath = getTemplatesDirectoryPath() ) type Controller struct { @@ -74,15 +79,15 @@ func (t *Controller) parsePageTemplates(p Page) error { template.New(p.Layout+TemplateExt). Funcs(funcMap). ParseFiles( - fmt.Sprintf("%s/layouts/%s%s", TemplateDir, p.Layout, TemplateExt), - fmt.Sprintf("%s/pages/%s%s", TemplateDir, p.Name, TemplateExt), + fmt.Sprintf("%s/layouts/%s%s", templatePath, p.Layout, TemplateExt), + fmt.Sprintf("%s/pages/%s%s", templatePath, p.Name, TemplateExt), ) if err != nil { return err } - parsed, err = parsed.ParseGlob(fmt.Sprintf("%s/components/*%s", TemplateDir, TemplateExt)) + parsed, err = parsed.ParseGlob(fmt.Sprintf("%s/components/*%s", templatePath, TemplateExt)) if err != nil { return err @@ -98,3 +103,12 @@ func (t *Controller) parsePageTemplates(p Page) error { func (t *Controller) Redirect(c echo.Context, route string, routeParams ...interface{}) error { return c.Redirect(http.StatusFound, c.Echo().Reverse(route, routeParams)) } + +// getTemplatesDirectoryPath gets the templates directory path +// This is needed incase this is called from a package outside of main, +// such as testing +func getTemplatesDirectoryPath() string { + _, b, _, _ := runtime.Caller(0) + d := path.Join(path.Dir(b)) + return filepath.Join(filepath.Dir(d), TemplateDir) +} diff --git a/controllers/controller_test.go b/controllers/controller_test.go new file mode 100644 index 0000000..3abcd46 --- /dev/null +++ b/controllers/controller_test.go @@ -0,0 +1,48 @@ +package controllers + +import ( + "net/http" + "net/http/httptest" + "os" + "testing" + + "goweb/container" + + "github.com/PuerkitoBio/goquery" + "github.com/stretchr/testify/assert" + + "github.com/labstack/gommon/log" + "github.com/stretchr/testify/require" +) + +var ( + srv *httptest.Server + c *container.Container +) + +func TestMain(m *testing.M) { + // Start a test HTTP server + c = container.NewContainer() + BuildRouter(c) + c.Web.Logger.SetLevel(log.DEBUG) + srv = httptest.NewServer(c.Web) + + exitVal := m.Run() + srv.Close() + os.Exit(exitVal) +} + +func GetRequest(t *testing.T, route string, routeParams ...interface{}) *http.Response { + cli := http.Client{} + resp, err := cli.Get(srv.URL + c.Web.Reverse(route, routeParams)) + require.NoError(t, err) + return resp +} + +func GetGoqueryDoc(t *testing.T, resp *http.Response) *goquery.Document { + doc, err := goquery.NewDocumentFromReader(resp.Body) + require.NoError(t, err) + err = resp.Body.Close() + assert.NoError(t, err) + return doc +} diff --git a/router/router.go b/controllers/router.go similarity index 76% rename from router/router.go rename to controllers/router.go index 8bd08d0..08d51f5 100644 --- a/router/router.go +++ b/controllers/router.go @@ -1,4 +1,4 @@ -package router +package controllers import ( "net/http" @@ -11,7 +11,6 @@ import ( echomw "github.com/labstack/echo/v4/middleware" "goweb/container" - "goweb/controllers" ) const StaticDir = "static" @@ -37,10 +36,10 @@ func BuildRouter(c *container.Container) { Static("/", StaticDir) // Base controller - ctr := controllers.NewController(c) + ctr := NewController(c) // Error handler - err := controllers.Error{Controller: ctr} + err := Error{Controller: ctr} c.Web.HTTPErrorHandler = err.Get // Routes @@ -48,24 +47,24 @@ func BuildRouter(c *container.Container) { userRoutes(c.Web, ctr) } -func navRoutes(e *echo.Echo, ctr controllers.Controller) { - home := controllers.Home{Controller: ctr} +func navRoutes(e *echo.Echo, ctr Controller) { + home := Home{Controller: ctr} e.GET("/", home.Get).Name = "home" - about := controllers.About{Controller: ctr} + about := About{Controller: ctr} e.GET("/about", about.Get).Name = "about" - contact := controllers.Contact{Controller: ctr} + contact := Contact{Controller: ctr} e.GET("/contact", contact.Get).Name = "contact" e.POST("/contact", contact.Post).Name = "contact.post" } -func userRoutes(e *echo.Echo, ctr controllers.Controller) { - login := controllers.Login{Controller: ctr} +func userRoutes(e *echo.Echo, ctr Controller) { + login := Login{Controller: ctr} e.GET("/user/login", login.Get).Name = "login" e.POST("/user/login", login.Post).Name = "login.post" - register := controllers.Register{Controller: ctr} + register := Register{Controller: ctr} e.GET("/user/register", register.Get).Name = "register" e.POST("/user/register", register.Post).Name = "register.post" } diff --git a/go.mod b/go.mod index bf59469..3277099 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,9 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect + github.com/PuerkitoBio/goquery v1.8.0 // indirect + github.com/andybalholm/cascadia v1.3.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/google/uuid v1.0.0 // indirect github.com/gorilla/context v1.1.1 // indirect @@ -22,6 +25,8 @@ require ( github.com/mattn/go-isatty v0.0.14 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/testify v1.7.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect @@ -29,4 +34,5 @@ require ( golang.org/x/sys v0.0.0-20211124211545-fe61309f8881 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect ) diff --git a/go.sum b/go.sum index f9135cc..e5a4962 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= +github.com/PuerkitoBio/goquery v1.8.0/go.mod h1:ypIiRMtY7COPGk+I/YbZLbxsxn9g5ejnI2HSMtkjZvI= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -21,6 +23,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= +github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= @@ -385,6 +389,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= diff --git a/main.go b/main.go index 529eac8..7c57630 100644 --- a/main.go +++ b/main.go @@ -10,7 +10,7 @@ import ( "goweb/config" "goweb/container" - "goweb/router" + "goweb/controllers" "github.com/labstack/gommon/log" ) @@ -27,7 +27,7 @@ func main() { } // Build the router - router.BuildRouter(c) + controllers.BuildRouter(c) // Start the server go func() {