mirror of
https://github.com/yusing/godoxy.git
synced 2026-01-16 23:26:47 +01:00
- Added ShortLinkMatcher to handle short link routing. - Integrated short link handling in Entrypoint. - Introduced tests for short link matching and dispatching. - Configured default domain suffix for subdomain aliases.
195 lines
5.7 KiB
Go
195 lines
5.7 KiB
Go
package entrypoint_test
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/yusing/godoxy/internal/common"
|
|
. "github.com/yusing/godoxy/internal/entrypoint"
|
|
)
|
|
|
|
func TestShortLinkMatcher_FQDNAlias(t *testing.T) {
|
|
ep := NewEntrypoint()
|
|
matcher := ep.ShortLinkMatcher()
|
|
matcher.AddRoute("app.domain.com")
|
|
|
|
t.Run("exact path", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.domain.com/", w.Header().Get("Location"))
|
|
})
|
|
|
|
t.Run("with path remainder", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app/foo/bar", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.domain.com/foo/bar", w.Header().Get("Location"))
|
|
})
|
|
|
|
t.Run("with query", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app/foo?x=y&z=1", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.domain.com/foo?x=y&z=1", w.Header().Get("Location"))
|
|
})
|
|
}
|
|
|
|
func TestShortLinkMatcher_SubdomainAlias(t *testing.T) {
|
|
ep := NewEntrypoint()
|
|
matcher := ep.ShortLinkMatcher()
|
|
matcher.SetDefaultDomainSuffix(".example.com")
|
|
matcher.AddRoute("app")
|
|
|
|
t.Run("exact path", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.example.com/", w.Header().Get("Location"))
|
|
})
|
|
|
|
t.Run("with path remainder", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app/foo/bar", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.example.com/foo/bar", w.Header().Get("Location"))
|
|
})
|
|
}
|
|
|
|
func TestShortLinkMatcher_NotFound(t *testing.T) {
|
|
ep := NewEntrypoint()
|
|
matcher := ep.ShortLinkMatcher()
|
|
matcher.SetDefaultDomainSuffix(".example.com")
|
|
matcher.AddRoute("app")
|
|
|
|
t.Run("missing key", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, w.Code)
|
|
})
|
|
|
|
t.Run("unknown key", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/unknown", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusNotFound, w.Code)
|
|
})
|
|
}
|
|
|
|
func TestShortLinkMatcher_AddDelRoute(t *testing.T) {
|
|
ep := NewEntrypoint()
|
|
matcher := ep.ShortLinkMatcher()
|
|
matcher.SetDefaultDomainSuffix(".example.com")
|
|
|
|
matcher.AddRoute("app1")
|
|
matcher.AddRoute("app2.domain.com")
|
|
|
|
t.Run("both routes work", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app1", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app1.example.com/", w.Header().Get("Location"))
|
|
|
|
req = httptest.NewRequest("GET", "/app2.domain.com", nil)
|
|
w = httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app2.domain.com/", w.Header().Get("Location"))
|
|
})
|
|
|
|
t.Run("delete route", func(t *testing.T) {
|
|
matcher.DelRoute("app1")
|
|
|
|
req := httptest.NewRequest("GET", "/app1", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusNotFound, w.Code)
|
|
|
|
req = httptest.NewRequest("GET", "/app2.domain.com", nil)
|
|
w = httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app2.domain.com/", w.Header().Get("Location"))
|
|
})
|
|
}
|
|
|
|
func TestShortLinkMatcher_NoDefaultDomainSuffix(t *testing.T) {
|
|
ep := NewEntrypoint()
|
|
matcher := ep.ShortLinkMatcher()
|
|
// no SetDefaultDomainSuffix called
|
|
|
|
t.Run("subdomain alias ignored", func(t *testing.T) {
|
|
matcher.AddRoute("app")
|
|
|
|
req := httptest.NewRequest("GET", "/app", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusNotFound, w.Code)
|
|
})
|
|
|
|
t.Run("FQDN alias still works", func(t *testing.T) {
|
|
matcher.AddRoute("app.domain.com")
|
|
|
|
req := httptest.NewRequest("GET", "/app.domain.com", nil)
|
|
w := httptest.NewRecorder()
|
|
matcher.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.domain.com/", w.Header().Get("Location"))
|
|
})
|
|
}
|
|
|
|
func TestEntrypoint_ShortLinkDispatch(t *testing.T) {
|
|
ep := NewEntrypoint()
|
|
ep.ShortLinkMatcher().SetDefaultDomainSuffix(".example.com")
|
|
ep.ShortLinkMatcher().AddRoute("app")
|
|
|
|
t.Run("shortlink host", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app", nil)
|
|
req.Host = common.ShortLinkPrefix
|
|
w := httptest.NewRecorder()
|
|
ep.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.example.com/", w.Header().Get("Location"))
|
|
})
|
|
|
|
t.Run("shortlink host with port", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app", nil)
|
|
req.Host = common.ShortLinkPrefix + ":8080"
|
|
w := httptest.NewRecorder()
|
|
ep.ServeHTTP(w, req)
|
|
|
|
assert.Equal(t, http.StatusTemporaryRedirect, w.Code)
|
|
assert.Equal(t, "https://app.example.com/", w.Header().Get("Location"))
|
|
})
|
|
|
|
t.Run("normal host", func(t *testing.T) {
|
|
req := httptest.NewRequest("GET", "/app", nil)
|
|
req.Host = "app.example.com"
|
|
w := httptest.NewRecorder()
|
|
ep.ServeHTTP(w, req)
|
|
|
|
// Should not redirect, should try normal route lookup (which will 404)
|
|
assert.NotEqual(t, http.StatusTemporaryRedirect, w.Code)
|
|
})
|
|
}
|