satellite/admin: Response 404 when entity not found
* Add test cases to verify that all the endpoint that target a specific entity respond 404 status code when the entity isn't found. * Fix the endpoints that target a specific entity which responded a 500 status code response when the entity didn't exist to respond with 404 status code. Additionally: * Simplify some tests using an existing test helper function. * Rename test functions to start with the entity name (e.g. Project, User, etc.) for easing to run a set of test with the `-run` Go test flag. Change-Id: I82aad92e429207b72932ad4b79c08db6b486a19a
This commit is contained in:
parent
fb0d055a41
commit
05960b2cf0
@ -4,7 +4,9 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
@ -127,6 +129,11 @@ func (server *Server) deleteAPIKey(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
info, err := server.db.Console().APIKeys().GetByHead(ctx, apikey.Head())
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, "API key does not exist",
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
sendJSONError(w, "could not get apikey id",
|
||||
err.Error(), http.StatusInternalServerError)
|
||||
@ -167,6 +174,11 @@ func (server *Server) deleteAPIKeyByName(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
info, err := server.db.Console().APIKeys().GetByNameAndProjectID(ctx, apikeyName, projectUUID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, "API key with specified name does not exist",
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
sendJSONError(w, "could not get apikey id",
|
||||
err.Error(), http.StatusInternalServerError)
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"storj.io/storj/satellite/console"
|
||||
)
|
||||
|
||||
func TestAddApiKey(t *testing.T) {
|
||||
func TestApiKeyAdd(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -75,7 +75,7 @@ func TestAddApiKey(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteApiKey(t *testing.T) {
|
||||
func TestApiKeyDelete(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -94,26 +94,22 @@ func TestDeleteApiKey(t *testing.T) {
|
||||
require.Len(t, keys.APIKeys, 1)
|
||||
|
||||
apikey := planet.Uplinks[0].APIKey[planet.Satellites[0].ID()].Serialize()
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, fmt.Sprintf("http://"+address.String()+"/api/apikeys/%s", apikey), nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Len(t, responseBody, 0)
|
||||
link := fmt.Sprintf("http://"+address.String()+"/api/apikeys/%s", apikey)
|
||||
body := assertReq(ctx, t, link, http.MethodDelete, "", http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Len(t, body, 0)
|
||||
|
||||
keys, err = planet.Satellites[0].DB.Console().APIKeys().GetPagedByProjectID(ctx, projectID, console.APIKeyCursor{Page: 1, Limit: 10})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, keys.APIKeys, 0)
|
||||
|
||||
// Delete a deleted key returns Not Found.
|
||||
body = assertReq(ctx, t, link, http.MethodDelete, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteApiKeyByName(t *testing.T) {
|
||||
func TestApiKeyDelete_ByName(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -131,26 +127,21 @@ func TestDeleteApiKeyByName(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Len(t, keys.APIKeys, 1)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, fmt.Sprintf("http://"+address.String()+"/api/projects/%s/apikeys/%s", projectID.String(), keys.APIKeys[0].Name), nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Len(t, responseBody, 0)
|
||||
link := fmt.Sprintf("http://"+address.String()+"/api/projects/%s/apikeys/%s", projectID.String(), keys.APIKeys[0].Name)
|
||||
body := assertReq(ctx, t, link, http.MethodDelete, "", http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Len(t, body, 0)
|
||||
|
||||
keys, err = planet.Satellites[0].DB.Console().APIKeys().GetPagedByProjectID(ctx, projectID, console.APIKeyCursor{Page: 1, Limit: 10})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, keys.APIKeys, 0)
|
||||
|
||||
// Delete a deleted key returns Not Found.
|
||||
body = assertReq(ctx, t, link, http.MethodDelete, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
}
|
||||
|
||||
func TestListAPIKeys(t *testing.T) {
|
||||
func TestApiKeysList(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
|
@ -107,6 +107,11 @@ func (server *Server) getProjectLimit(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
project, err := server.db.Console().Projects().Get(ctx, projectUUID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, "project with specified uuid does not exist",
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
sendJSONError(w, "failed to get project",
|
||||
err.Error(), http.StatusInternalServerError)
|
||||
@ -192,6 +197,19 @@ func (server *Server) putProjectLimit(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// check if the project exists.
|
||||
_, err = server.db.Console().Projects().Get(ctx, projectUUID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, "project with specified uuid does not exist",
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
sendJSONError(w, "failed to get project",
|
||||
err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
if arguments.Usage != nil {
|
||||
if *arguments.Usage < 0 {
|
||||
sendJSONError(w, "negative usage",
|
||||
@ -355,7 +373,7 @@ func (server *Server) renameProject(w http.ResponseWriter, r *http.Request) {
|
||||
project, err := server.db.Console().Projects().Get(ctx, projectUUID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, "project with specified uuid does not exist",
|
||||
"", http.StatusBadRequest)
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
"storj.io/storj/satellite/console"
|
||||
)
|
||||
|
||||
func TestAPI(t *testing.T) {
|
||||
func TestProjectGet(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -42,11 +42,8 @@ func TestAPI(t *testing.T) {
|
||||
project, err := sat.DB.Console().Projects().Get(ctx, planet.Uplinks[0].Projects[0].ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
link := "http://" + address.String() + "/api/projects/" + project.ID.String()
|
||||
linkLimit := link + "/limit"
|
||||
|
||||
t.Run("GetProject", func(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
link := "http://" + address.String() + "/api/projects/" + project.ID.String()
|
||||
expected := fmt.Sprintf(
|
||||
`{"id":"%s","name":"%s","description":"%s","partnerId":"%s","ownerId":"%s","rateLimit":null,"burstLimit":null,"maxBuckets":null,"createdAt":"%s","memberCount":0,"storageLimit":"25.00 GB","bandwidthLimit":"25.00 GB"}`,
|
||||
project.ID.String(),
|
||||
@ -59,11 +56,73 @@ func TestAPI(t *testing.T) {
|
||||
assertGet(ctx, t, link, expected, planet.Satellites[0].Config.Console.AuthToken)
|
||||
})
|
||||
|
||||
t.Run("GetProjectLimits", func(t *testing.T) {
|
||||
t.Run("Not Found", func(t *testing.T) {
|
||||
id, err := uuid.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
link := "http://" + address.String() + "/api/projects/" + id.String() + "/limit"
|
||||
body := assertReq(ctx, t, link, http.MethodGet, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectLimit(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
sat := planet.Satellites[0]
|
||||
address := sat.Admin.Admin.Listener.Addr()
|
||||
project, err := sat.DB.Console().Projects().Get(ctx, planet.Uplinks[0].Projects[0].ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
linkLimit := "http://" + address.String() + "/api/projects/" + project.ID.String() + "/limit"
|
||||
|
||||
t.Run("Get OK", func(t *testing.T) {
|
||||
assertGet(ctx, t, linkLimit, `{"usage":{"amount":"25.00 GB","bytes":25000000000},"bandwidth":{"amount":"25.00 GB","bytes":25000000000},"rate":{"rps":0},"maxBuckets":0}`, planet.Satellites[0].Config.Console.AuthToken)
|
||||
})
|
||||
|
||||
t.Run("UpdateUsage", func(t *testing.T) {
|
||||
t.Run("Get Not Found", func(t *testing.T) {
|
||||
id, err := uuid.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
link := "http://" + address.String() + "/api/projects/" + id.String() + "/limit"
|
||||
body := assertReq(ctx, t, link, http.MethodGet, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
|
||||
t.Run("Update Not Found", func(t *testing.T) {
|
||||
id, err := uuid.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
link := "http://" + address.String() + "/api/projects/" + id.String() + "/limit?usage=100000000"
|
||||
body := assertReq(ctx, t, link, http.MethodPut, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
|
||||
t.Run("Update Nothing", func(t *testing.T) {
|
||||
expectedBody := assertReq(ctx, t, linkLimit, http.MethodGet, "", http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, linkLimit, nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.NoError(t, response.Body.Close())
|
||||
|
||||
assertGet(ctx, t, linkLimit, string(expectedBody), planet.Satellites[0].Config.Console.AuthToken)
|
||||
})
|
||||
|
||||
t.Run("Update Usage", func(t *testing.T) {
|
||||
data := url.Values{"usage": []string{"1TiB"}}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, linkLimit, strings.NewReader(data.Encode()))
|
||||
require.NoError(t, err)
|
||||
@ -89,7 +148,7 @@ func TestAPI(t *testing.T) {
|
||||
assertGet(ctx, t, linkLimit, `{"usage":{"amount":"1.00 GB","bytes":1000000000},"bandwidth":{"amount":"25.00 GB","bytes":25000000000},"rate":{"rps":0},"maxBuckets":0}`, planet.Satellites[0].Config.Console.AuthToken)
|
||||
})
|
||||
|
||||
t.Run("UpdateBandwidth", func(t *testing.T) {
|
||||
t.Run("Update Bandwidth", func(t *testing.T) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, linkLimit+"?bandwidth=1MB", nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
@ -102,7 +161,7 @@ func TestAPI(t *testing.T) {
|
||||
assertGet(ctx, t, linkLimit, `{"usage":{"amount":"1.00 GB","bytes":1000000000},"bandwidth":{"amount":"1.00 MB","bytes":1000000},"rate":{"rps":0},"maxBuckets":0}`, planet.Satellites[0].Config.Console.AuthToken)
|
||||
})
|
||||
|
||||
t.Run("UpdateRate", func(t *testing.T) {
|
||||
t.Run("Update Rate", func(t *testing.T) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, linkLimit+"?rate=100", nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
@ -114,7 +173,8 @@ func TestAPI(t *testing.T) {
|
||||
|
||||
assertGet(ctx, t, linkLimit, `{"usage":{"amount":"1.00 GB","bytes":1000000000},"bandwidth":{"amount":"1.00 MB","bytes":1000000},"rate":{"rps":100},"maxBuckets":0}`, planet.Satellites[0].Config.Console.AuthToken)
|
||||
})
|
||||
t.Run("UpdateBuckets", func(t *testing.T) {
|
||||
|
||||
t.Run("Update Buckets", func(t *testing.T) {
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, linkLimit+"?buckets=2000", nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
@ -129,7 +189,7 @@ func TestAPI(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddProject(t *testing.T) {
|
||||
func TestProjectAdd(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -169,7 +229,7 @@ func TestAddProject(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestRenameProject(t *testing.T) {
|
||||
func TestProjectRename(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -188,24 +248,36 @@ func TestRenameProject(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, oldName, project.Name)
|
||||
|
||||
body := strings.NewReader(fmt.Sprintf(`{"projectName":"%s","description":"This project got renamed"}`, newName))
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("http://"+address.String()+"/api/projects/%s", project.ID.String()), body)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
body := strings.NewReader(fmt.Sprintf(`{"projectName":"%s","description":"This project got renamed"}`, newName))
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("http://"+address.String()+"/api/projects/%s", project.ID.String()), body)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
require.NoError(t, response.Body.Close())
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
require.NoError(t, response.Body.Close())
|
||||
|
||||
project, err = planet.Satellites[0].DB.Console().Projects().Get(ctx, project.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newName, project.Name)
|
||||
project, err = planet.Satellites[0].DB.Console().Projects().Get(ctx, project.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, newName, project.Name)
|
||||
})
|
||||
|
||||
t.Run("Not Found", func(t *testing.T) {
|
||||
id, err := uuid.New()
|
||||
require.NoError(t, err)
|
||||
|
||||
link := fmt.Sprintf("http://"+address.String()+"/api/projects/%s", id.String())
|
||||
putBody := fmt.Sprintf(`{"projectName":"%s","description":"This project got renamed"}`, newName)
|
||||
body := assertReq(ctx, t, link, http.MethodPut, putBody, http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteProject(t *testing.T) {
|
||||
func TestProjectDelete(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -262,7 +334,7 @@ func TestDeleteProject(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckUsageWithoutUsage(t *testing.T) {
|
||||
func TestProjectCheckUsage_withoutUsage(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -302,7 +374,7 @@ func TestCheckUsageWithoutUsage(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckUsageWithUsage(t *testing.T) {
|
||||
func TestProjectCheckUsage_withUsage(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -368,7 +440,7 @@ func TestCheckUsageWithUsage(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckUsageLastMonthUnappliedInvoice(t *testing.T) {
|
||||
func TestProjectCheckUsage_lastMonthUnappliedInvoice(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -446,7 +518,7 @@ func TestCheckUsageLastMonthUnappliedInvoice(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteProjectWithUsageCurrentMonth(t *testing.T) {
|
||||
func TestProjectDelete_withUsageCurrentMonth(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -512,7 +584,7 @@ func TestDeleteProjectWithUsageCurrentMonth(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteProjectWithUsagePreviousMonth(t *testing.T) {
|
||||
func TestProjectDelete_withUsagePreviousMonth(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
|
@ -130,7 +130,7 @@ func (server *Server) userInfo(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
user, err := server.db.Console().Users().GetByEmail(ctx, userEmail)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, fmt.Sprintf("user with email %q not found", userEmail),
|
||||
sendJSONError(w, fmt.Sprintf("user with email %q does not exist", userEmail),
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
@ -213,7 +213,7 @@ func (server *Server) updateUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
user, err := server.db.Console().Users().GetByEmail(ctx, userEmail)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, fmt.Sprintf("user with email %q not found", userEmail),
|
||||
sendJSONError(w, fmt.Sprintf("user with email %q does not exist", userEmail),
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
@ -278,7 +278,7 @@ func (server *Server) deleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
user, err := server.db.Console().Users().GetByEmail(ctx, userEmail)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
sendJSONError(w, fmt.Sprintf("user with email %q not found", userEmail),
|
||||
sendJSONError(w, fmt.Sprintf("user with email %q does not exist", userEmail),
|
||||
"", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import (
|
||||
"storj.io/storj/satellite/console"
|
||||
)
|
||||
|
||||
func TestGetUser(t *testing.T) {
|
||||
func TestUserGet(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -44,34 +44,21 @@ func TestGetUser(t *testing.T) {
|
||||
couponsMarshaled, err := json.Marshal(coupons)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("GetUser", func(t *testing.T) {
|
||||
userLink := "http://" + address.String() + "/api/users/" + project.Owner.Email
|
||||
expected := `{` +
|
||||
fmt.Sprintf(`"user":{"id":"%s","fullName":"User uplink0_0","email":"%s","projectLimit":%d},`, project.Owner.ID, project.Owner.Email, projLimit) +
|
||||
fmt.Sprintf(`"projects":[{"id":"%s","name":"uplink0_0","description":"","ownerId":"%s"}],`, project.ID, project.Owner.ID) +
|
||||
fmt.Sprintf(`"coupons":%s}`, couponsMarshaled)
|
||||
link := "http://" + address.String() + "/api/users/" + project.Owner.Email
|
||||
expectedBody := `{` +
|
||||
fmt.Sprintf(`"user":{"id":"%s","fullName":"User uplink0_0","email":"%s","projectLimit":%d},`, project.Owner.ID, project.Owner.Email, projLimit) +
|
||||
fmt.Sprintf(`"projects":[{"id":"%s","name":"uplink0_0","description":"","ownerId":"%s"}],`, project.ID, project.Owner.ID) +
|
||||
fmt.Sprintf(`"coupons":%s}`, couponsMarshaled)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, userLink, nil)
|
||||
require.NoError(t, err)
|
||||
assertReq(ctx, t, link, http.MethodGet, "", http.StatusOK, expectedBody, planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "application/json", response.Header.Get("Content-Type"))
|
||||
|
||||
data, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
|
||||
require.Equal(t, http.StatusOK, response.StatusCode, string(data))
|
||||
require.Equal(t, expected, string(data))
|
||||
})
|
||||
link = "http://" + address.String() + "/api/users/" + "user-not-exist@not-exist.test"
|
||||
body := assertReq(ctx, t, link, http.MethodGet, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddUser(t *testing.T) {
|
||||
func TestUserAdd(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -110,7 +97,7 @@ func TestAddUser(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestAddUserSameEmail(t *testing.T) {
|
||||
func TestUserAdd_sameEmail(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -161,7 +148,7 @@ func TestAddUserSameEmail(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateUser(t *testing.T) {
|
||||
func TestUserUpdate(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -176,73 +163,48 @@ func TestUpdateUser(t *testing.T) {
|
||||
user, err := planet.Satellites[0].DB.Console().Users().GetByEmail(ctx, planet.Uplinks[0].Projects[0].Owner.Email)
|
||||
require.NoError(t, err)
|
||||
|
||||
body := strings.NewReader(`{"email":"alice+2@mail.test", "shortName":"Newbie"}`)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email), body)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
// Updat user data.
|
||||
link := fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email)
|
||||
body := `{"email":"alice+2@mail.test", "shortName":"Newbie"}`
|
||||
responseBody := assertReq(ctx, t, link, http.MethodPut, body, http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Len(t, responseBody, 0)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Len(t, responseBody, 0)
|
||||
updatedUser, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "alice+2@mail.test", updatedUser.Email)
|
||||
require.Equal(t, user.FullName, updatedUser.FullName)
|
||||
require.NotEqual(t, "Newbie", user.ShortName)
|
||||
require.Equal(t, "Newbie", updatedUser.ShortName)
|
||||
require.Equal(t, user.ID, updatedUser.ID)
|
||||
require.Equal(t, user.Status, updatedUser.Status)
|
||||
require.Equal(t, user.ProjectLimit, updatedUser.ProjectLimit)
|
||||
|
||||
updatedUser, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "alice+2@mail.test", updatedUser.Email)
|
||||
require.Equal(t, user.FullName, updatedUser.FullName)
|
||||
require.NotEqual(t, "Newbie", user.ShortName)
|
||||
require.Equal(t, "Newbie", updatedUser.ShortName)
|
||||
require.Equal(t, user.ID, updatedUser.ID)
|
||||
require.Equal(t, user.Status, updatedUser.Status)
|
||||
require.Equal(t, user.ProjectLimit, updatedUser.ProjectLimit)
|
||||
// Update rate limit.
|
||||
link = "http://" + address.String() + "/api/users/alice+2@mail.test"
|
||||
newLimit := 50
|
||||
body = fmt.Sprintf(`{"projectLimit":%d}`, newLimit)
|
||||
responseBody = assertReq(ctx, t, link, http.MethodPut, body, http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Len(t, responseBody, 0)
|
||||
|
||||
updatedUserRate, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, updatedUser.Email, updatedUserRate.Email)
|
||||
require.Equal(t, updatedUser.ID, updatedUserRate.ID)
|
||||
require.Equal(t, updatedUser.Status, updatedUserRate.Status)
|
||||
require.Equal(t, newLimit, updatedUserRate.ProjectLimit)
|
||||
})
|
||||
|
||||
t.Run("Not found", func(t *testing.T) {
|
||||
link := "http://" + address.String() + "/api/users/user-not-exists@not-exists.test"
|
||||
body := `{"email":"alice+2@mail.test", "shortName":"Newbie"}`
|
||||
responseBody := assertReq(ctx, t, link, http.MethodPut, body, http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(responseBody), "does not exist")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateUserRateLimit(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
|
||||
address := planet.Satellites[0].Admin.Admin.Listener.Addr()
|
||||
user, err := planet.Satellites[0].DB.Console().Users().GetByEmail(ctx, planet.Uplinks[0].Projects[0].Owner.Email)
|
||||
require.NoError(t, err)
|
||||
|
||||
newLimit := 50
|
||||
|
||||
body := strings.NewReader(fmt.Sprintf(`{"projectLimit":%d}`, newLimit))
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPut, fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email), body)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Len(t, responseBody, 0)
|
||||
|
||||
updatedUser, err := planet.Satellites[0].DB.Console().Users().Get(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, user.Email, updatedUser.Email)
|
||||
require.Equal(t, user.ID, updatedUser.ID)
|
||||
require.Equal(t, user.Status, updatedUser.Status)
|
||||
require.Equal(t, newLimit, updatedUser.ProjectLimit)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteUser(t *testing.T) {
|
||||
func TestUserDelete(t *testing.T) {
|
||||
testplanet.Run(t, testplanet.Config{
|
||||
SatelliteCount: 1,
|
||||
StorageNodeCount: 0,
|
||||
@ -258,34 +220,19 @@ func TestDeleteUser(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Deleting the user should fail, as project exists
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email), nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
|
||||
response, err := http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusConflict, response.StatusCode)
|
||||
require.Equal(t, "application/json", response.Header.Get("Content-Type"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Greater(t, len(responseBody), 0)
|
||||
link := fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email)
|
||||
body := assertReq(ctx, t, link, http.MethodDelete, "", http.StatusConflict, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Greater(t, len(body), 0)
|
||||
|
||||
err = planet.Satellites[0].DB.Console().Projects().Delete(ctx, planet.Uplinks[0].Projects[0].ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Deleting the user should pass, as no project exists for given user
|
||||
req, err = http.NewRequestWithContext(ctx, http.MethodDelete, fmt.Sprintf("http://"+address.String()+"/api/users/%s", user.Email), nil)
|
||||
require.NoError(t, err)
|
||||
req.Header.Set("Authorization", planet.Satellites[0].Config.Console.AuthToken)
|
||||
// Deleting the user should pass, as no project exists for given user.
|
||||
body = assertReq(ctx, t, link, http.MethodDelete, "", http.StatusOK, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Len(t, body, 0)
|
||||
|
||||
response, err = http.DefaultClient.Do(req)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
responseBody, err = ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, len(responseBody), 0)
|
||||
// Deleting unexisting user returns Not Found.
|
||||
body = assertReq(ctx, t, link, http.MethodDelete, "", http.StatusNotFound, "", planet.Satellites[0].Config.Console.AuthToken)
|
||||
require.Contains(t, string(body), "does not exist")
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user