mirror of https://github.com/grafana/grafana
fix(short-url): redirect to main page if not found (#97347)
parent
802b96c6f7
commit
5bf0872d14
@ -0,0 +1,130 @@ |
||||
package shorturl |
||||
|
||||
import ( |
||||
"bytes" |
||||
"context" |
||||
"encoding/json" |
||||
"fmt" |
||||
"io" |
||||
"net/http" |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/require" |
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db" |
||||
"github.com/grafana/grafana/pkg/infra/tracing" |
||||
"github.com/grafana/grafana/pkg/services/org" |
||||
"github.com/grafana/grafana/pkg/services/org/orgimpl" |
||||
"github.com/grafana/grafana/pkg/services/quota/quotaimpl" |
||||
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest" |
||||
"github.com/grafana/grafana/pkg/services/user" |
||||
"github.com/grafana/grafana/pkg/services/user/userimpl" |
||||
"github.com/grafana/grafana/pkg/setting" |
||||
"github.com/grafana/grafana/pkg/tests/testinfra" |
||||
"github.com/grafana/grafana/pkg/tests/testsuite" |
||||
) |
||||
|
||||
func TestMain(m *testing.M) { |
||||
testsuite.Run(m) |
||||
} |
||||
|
||||
func TestShortURL(t *testing.T) { |
||||
dir, path := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{ |
||||
AppModeProduction: true, |
||||
}) |
||||
|
||||
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path) |
||||
|
||||
username, password := "viewer", "viewer" |
||||
createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{ |
||||
DefaultOrgRole: string(org.RoleEditor), |
||||
Password: user.Password(password), |
||||
Login: username, |
||||
}) |
||||
|
||||
c := client(grafanaListedAddr, username, password) |
||||
|
||||
// Create a valid short-urls
|
||||
res, err := c.post("/api/short-urls", bytes.NewReader([]byte(`{"path":"explore"}`))) |
||||
require.NoError(t, err) |
||||
defer func() { |
||||
_ = res.Body.Close() |
||||
}() |
||||
require.Equal(t, http.StatusOK, res.StatusCode) |
||||
|
||||
bodyRaw, err := io.ReadAll(res.Body) |
||||
require.NoError(t, err) |
||||
|
||||
resParsed := struct { |
||||
UID string `json:"uid"` |
||||
}{} |
||||
err = json.Unmarshal(bodyRaw, &resParsed) |
||||
require.NoError(t, err) |
||||
|
||||
// If the go-to exists, it should be set in the location and the status should match 302.
|
||||
res, err = c.get(fmt.Sprintf("/goto/%s", resParsed.UID)) |
||||
require.NoError(t, err) |
||||
defer func() { |
||||
_ = res.Body.Close() |
||||
}() |
||||
require.Equal(t, "http://localhost:3000/explore", res.Header.Get("Location")) |
||||
require.Equal(t, http.StatusFound, res.StatusCode) |
||||
|
||||
// If the go-to does not exist, it should redirect to the home page and return 308.
|
||||
res, err = c.get("/goto/DoesNotExist") |
||||
require.NoError(t, err) |
||||
defer func() { |
||||
_ = res.Body.Close() |
||||
}() |
||||
require.Equal(t, "http://localhost:3000/", res.Header.Get("Location")) |
||||
require.Equal(t, http.StatusPermanentRedirect, res.StatusCode) |
||||
} |
||||
|
||||
func createUser(t *testing.T, db db.DB, cfg *setting.Cfg, cmd user.CreateUserCommand) int64 { |
||||
t.Helper() |
||||
|
||||
cfg.AutoAssignOrg = true |
||||
cfg.AutoAssignOrgId = 1 |
||||
|
||||
quotaService := quotaimpl.ProvideService(db, cfg) |
||||
orgService, err := orgimpl.ProvideService(db, cfg, quotaService) |
||||
require.NoError(t, err) |
||||
usrSvc, err := userimpl.ProvideService( |
||||
db, orgService, cfg, nil, nil, tracing.InitializeTracerForTest(), |
||||
quotaService, supportbundlestest.NewFakeBundleService(), |
||||
) |
||||
require.NoError(t, err) |
||||
|
||||
u, err := usrSvc.Create(context.Background(), &cmd) |
||||
require.NoError(t, err) |
||||
return u.ID |
||||
} |
||||
|
||||
type apiClient struct { |
||||
url string |
||||
} |
||||
|
||||
func client(host, user, pass string) apiClient { |
||||
if len(user) == 0 && len(pass) == 0 { |
||||
return apiClient{url: fmt.Sprintf("http://%s", host)} |
||||
} |
||||
return apiClient{url: fmt.Sprintf("http://%s:%s@%s", user, pass, host)} |
||||
} |
||||
|
||||
func (a apiClient) get(path string) (*http.Response, error) { |
||||
u := fmt.Sprintf("%s%s", a.url, path) |
||||
// Setup a client that doesn't follow redirects.
|
||||
client := &http.Client{ |
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error { |
||||
return http.ErrUseLastResponse |
||||
}, |
||||
} |
||||
// nolint:gosec
|
||||
return client.Get(u) |
||||
} |
||||
|
||||
func (a apiClient) post(path string, body io.Reader) (*http.Response, error) { |
||||
u := fmt.Sprintf("%s%s", a.url, path) |
||||
// nolint:gosec
|
||||
return http.Post(u, "application/json", body) |
||||
} |
Loading…
Reference in new issue