diff --git a/assets.go b/assets.go index 48f3b1eb..9c0946b8 100644 --- a/assets.go +++ b/assets.go @@ -9,8 +9,10 @@ import ( ) func init() { - // Scripts - scripts := js.Bundle() + // Script bundle + scriptBundle := js.Bundle() + + // Service worker serviceWorkerBytes, err := ioutil.ReadFile("sw/service-worker.js") serviceWorker := string(serviceWorkerBytes) @@ -19,18 +21,15 @@ func init() { } app.Get("/scripts", func(ctx *aero.Context) string { - ctx.SetResponseHeader("Content-Type", "application/javascript") - return scripts + return ctx.JavaScript(scriptBundle) }) app.Get("/scripts.js", func(ctx *aero.Context) string { - ctx.SetResponseHeader("Content-Type", "application/javascript") - return scripts + return ctx.JavaScript(scriptBundle) }) app.Get("/service-worker", func(ctx *aero.Context) string { - ctx.SetResponseHeader("Content-Type", "application/javascript") - return serviceWorker + return ctx.JavaScript(serviceWorker) }) // Web manifest diff --git a/main.go b/main.go index f0dd2d35..12c0c193 100644 --- a/main.go +++ b/main.go @@ -153,6 +153,9 @@ func configure(app *aero.Application) *aero.Application { app.Ajax("/paypal/cancel", paypal.Cancel) app.Get("/api/paypal/payment/create", paypal.CreatePayment) + // Rewrite + app.Rewrite(Rewrite) + // Middleware app.Use(middleware.Firewall()) app.Use(middleware.Log()) @@ -173,5 +176,10 @@ func configure(app *aero.Application) *aero.Application { // Authentication auth.Install(app) + // Specify test routes + for route, examples := range routeTests { + app.Test(route, examples) + } + return app } diff --git a/main_test.go b/main_test.go index 4daa0c38..80f99509 100644 --- a/main_test.go +++ b/main_test.go @@ -1,11 +1,16 @@ package main import ( + "errors" "net/http" "net/http/httptest" + "reflect" "testing" "github.com/aerogo/aero" + "github.com/aerogo/api" + "github.com/animenotifier/arn" + "github.com/fatih/color" ) func TestRoutes(t *testing.T) { @@ -23,9 +28,55 @@ func TestRoutes(t *testing.T) { app.Handler().ServeHTTP(responseRecorder, request) if status := responseRecorder.Code; status != http.StatusOK { - t.Errorf("%s | Wrong status code | %v instead of %v", example, status, http.StatusOK) - } else { - t.Logf("%s | Correct status code | %v == %v", example, status, http.StatusOK) + color.Red("%s | Wrong status code | %v instead of %v", example, status, http.StatusOK) + } + } + } +} + +func TestInterfaceImplementations(t *testing.T) { + // API interfaces + var creatable = reflect.TypeOf((*api.Creatable)(nil)).Elem() + var updatable = reflect.TypeOf((*api.Updatable)(nil)).Elem() + var actionable = reflect.TypeOf((*api.Actionable)(nil)).Elem() + var collection = reflect.TypeOf((*api.Collection)(nil)).Elem() + + // Required interface implementations + var interfaceImplementations = map[string][]reflect.Type{ + "User": []reflect.Type{ + updatable, + }, + "Thread": []reflect.Type{ + creatable, + updatable, + actionable, + }, + "Post": []reflect.Type{ + creatable, + updatable, + actionable, + }, + "SoundTrack": []reflect.Type{ + creatable, + }, + "Analytics": []reflect.Type{ + creatable, + }, + "AnimeList": []reflect.Type{ + collection, + }, + "PushSubscriptions": []reflect.Type{ + collection, + }, + "UserFollows": []reflect.Type{ + collection, + }, + } + + for typeName, interfaces := range interfaceImplementations { + for _, requiredInterface := range interfaces { + if !reflect.PtrTo(arn.DB.Type(typeName)).Implements(requiredInterface) { + panic(errors.New(typeName + " does not implement interface " + requiredInterface.Name())) } } } diff --git a/rewrite.go b/rewrite.go index 78d45abf..60096ead 100644 --- a/rewrite.go +++ b/rewrite.go @@ -6,48 +6,43 @@ import ( "github.com/aerogo/aero" ) -func init() { - plusRoute := "/+" - plusRouteAjax := "/_/+" +// Rewrite will rewrite certain routes +func Rewrite(ctx *aero.RewriteContext) { + requestURI := ctx.URI() - // This will rewrite /+UserName requests to /user/UserName - app.Rewrite(func(ctx *aero.RewriteContext) { - requestURI := ctx.URI() + // User profiles + if strings.HasPrefix(requestURI, "/+") { + newURI := "/user/" + userName := requestURI[2:] + ctx.SetURI(newURI + userName) + return + } - // User profiles - if strings.HasPrefix(requestURI, plusRoute) { - newURI := "/user/" - userName := requestURI[2:] - ctx.SetURI(newURI + userName) - return - } + if strings.HasPrefix(requestURI, "/_/+") { + newURI := "/_/user/" + userName := requestURI[4:] + ctx.SetURI(newURI + userName) + return + } - if strings.HasPrefix(requestURI, plusRouteAjax) { - newURI := "/_/user/" - userName := requestURI[4:] - ctx.SetURI(newURI + userName) - return - } + // Search + if strings.HasPrefix(requestURI, "/search/") { + searchTerm := requestURI[len("/search/"):] + ctx.Request.URL.RawQuery = "q=" + searchTerm + ctx.SetURI("/search") + return + } - // Search - if strings.HasPrefix(requestURI, "/search/") { - searchTerm := requestURI[len("/search/"):] - ctx.Request.URL.RawQuery = "q=" + searchTerm - ctx.SetURI("/search") - return - } + if strings.HasPrefix(requestURI, "/_/search/") { + searchTerm := requestURI[len("/_/search/"):] + ctx.Request.URL.RawQuery = "q=" + searchTerm + ctx.SetURI("/_/search") + return + } - if strings.HasPrefix(requestURI, "/_/search/") { - searchTerm := requestURI[len("/_/search/"):] - ctx.Request.URL.RawQuery = "q=" + searchTerm - ctx.SetURI("/_/search") - return - } - - // Analytics - if requestURI == "/dark-flame-master" { - ctx.SetURI("/api/new/analytics") - return - } - }) + // Analytics + if requestURI == "/dark-flame-master" { + ctx.SetURI("/api/new/analytics") + return + } } diff --git a/tests.go b/tests.go index 8d86176c..ff152fdc 100644 --- a/tests.go +++ b/tests.go @@ -1,13 +1,5 @@ package main -import ( - "errors" - "reflect" - - "github.com/aerogo/api" - "github.com/animenotifier/arn" -) - var routeTests = map[string][]string{ // User "/user/:nick": []string{ @@ -241,57 +233,3 @@ var routeTests = map[string][]string{ "/settings": nil, "/extension/embed": nil, } - -// API interfaces -var creatable = reflect.TypeOf((*api.Creatable)(nil)).Elem() -var updatable = reflect.TypeOf((*api.Updatable)(nil)).Elem() -var actionable = reflect.TypeOf((*api.Actionable)(nil)).Elem() -var collection = reflect.TypeOf((*api.Collection)(nil)).Elem() - -// Required interface implementations -var interfaceImplementations = map[string][]reflect.Type{ - "User": []reflect.Type{ - updatable, - }, - "Thread": []reflect.Type{ - creatable, - updatable, - actionable, - }, - "Post": []reflect.Type{ - creatable, - updatable, - actionable, - }, - "SoundTrack": []reflect.Type{ - creatable, - }, - "Analytics": []reflect.Type{ - creatable, - }, - "AnimeList": []reflect.Type{ - collection, - }, - "PushSubscriptions": []reflect.Type{ - collection, - }, - "UserFollows": []reflect.Type{ - collection, - }, -} - -func init() { - // Specify test routes - for route, examples := range routeTests { - app.Test(route, examples) - } - - // Check interface implementations - for typeName, interfaces := range interfaceImplementations { - for _, requiredInterface := range interfaces { - if !reflect.PtrTo(arn.DB.Type(typeName)).Implements(requiredInterface) { - panic(errors.New(typeName + " does not implement interface " + requiredInterface.Name())) - } - } - } -}