satellite/admin: Send JSON content-type for errors
Fix the Admin API endpoints when it response with a client error response code. The most of the client response error send a JSON body but the `Content-Type` header wasn't set to the appropriated value. This commit fixes them and it adds assertions to the tests to very the `Content-Type` header. Updates the README to briefly document about the format of the client errors endpoints responses. Change-Id: Ifaf2122def801701211438ce241046be1adc0e8c
This commit is contained in:
parent
821a077f7c
commit
bb575ef739
@ -7,38 +7,60 @@ Requires setting `Authorization` header for requests.
|
||||
<!-- Auto-generate this ToC with https://github.com/ycd/toc -->
|
||||
<!-- toc -->
|
||||
- [satellite/admin](#satelliteadmin)
|
||||
* [User Management](#user-management)
|
||||
* [POST /api/users](#post-apiusers)
|
||||
* [PUT /api/users/{user-email}](#put-apiusersuser-email)
|
||||
* [GET /api/users/{user-email}](#get-apiusersuser-email)
|
||||
* [DELETE /api/users/{user-email}](#delete-apiusersuser-email)
|
||||
* [Coupon Management](#coupon-management)
|
||||
* [POST /api/coupons](#post-apicoupons)
|
||||
* [GET /api/coupons/{coupon-id}](#get-apicouponscoupon-id)
|
||||
* [DELETE /api/coupons/{coupon-id}](#delete-apicouponscoupon-id)
|
||||
* [Project Management](#project-management)
|
||||
* [POST /api/projects](#post-apiprojects)
|
||||
* [GET /api/projects/{project-id}](#get-apiprojectsproject-id)
|
||||
* [PUT /api/projects/{project-id}](#put-apiprojectsproject-id)
|
||||
* [DELETE /api/projects/{project-id}](#delete-apiprojectsproject-id)
|
||||
* [GET /api/projects/{project}/apikeys](#get-apiprojectsprojectapikeys)
|
||||
* [POST /api/projects/{project}/apikeys](#post-apiprojectsprojectapikeys)
|
||||
* [DELETE /api/projects/{project}/apikeys/{name}](#delete-apiprojectsprojectapikeysname)
|
||||
* [GET /api/projects/{project-id}/usage](#get-apiprojectsproject-idusage)
|
||||
* [GET /api/projects/{project-id}/limit](#get-apiprojectsproject-idlimit)
|
||||
* [Update limits](#update-limits)
|
||||
* [POST /api/projects/{project-id}/limit?usage={value}](#post-apiprojectsproject-idlimitusagevalue)
|
||||
* [POST /api/projects/{project-id}/limit?bandwidth={value}](#post-apiprojectsproject-idlimitbandwidthvalue)
|
||||
* [POST /api/projects/{project-id}/limit?rate={value}](#post-apiprojectsproject-idlimitratevalue)
|
||||
* [POST /api/projects/{project-id}/limit?buckets={value}](#post-apiprojectsproject-idlimitbucketsvalue)
|
||||
* [APIKey Management](#apikey-management)
|
||||
* [DELETE /api/apikeys/{apikey}](#delete-apiapikeysapikey)
|
||||
* [API design](#api-design)
|
||||
* [Error responses](#error-responses)
|
||||
* [API Endpoints](#api-endpoints)
|
||||
* [User Management](#user-management)
|
||||
* [POST /api/users](#post-apiusers)
|
||||
* [PUT /api/users/{user-email}](#put-apiusersuser-email)
|
||||
* [GET /api/users/{user-email}](#get-apiusersuser-email)
|
||||
* [DELETE /api/users/{user-email}](#delete-apiusersuser-email)
|
||||
* [Coupon Management](#coupon-management)
|
||||
* [POST /api/coupons](#post-apicoupons)
|
||||
* [GET /api/coupons/{coupon-id}](#get-apicouponscoupon-id)
|
||||
* [DELETE /api/coupons/{coupon-id}](#delete-apicouponscoupon-id)
|
||||
* [Project Management](#project-management)
|
||||
* [POST /api/projects](#post-apiprojects)
|
||||
* [GET /api/projects/{project-id}](#get-apiprojectsproject-id)
|
||||
* [PUT /api/projects/{project-id}](#put-apiprojectsproject-id)
|
||||
* [DELETE /api/projects/{project-id}](#delete-apiprojectsproject-id)
|
||||
* [GET /api/projects/{project}/apikeys](#get-apiprojectsprojectapikeys)
|
||||
* [POST /api/projects/{project}/apikeys](#post-apiprojectsprojectapikeys)
|
||||
* [DELETE /api/projects/{project}/apikeys/{name}](#delete-apiprojectsprojectapikeysname)
|
||||
* [GET /api/projects/{project-id}/usage](#get-apiprojectsproject-idusage)
|
||||
* [GET /api/projects/{project-id}/limit](#get-apiprojectsproject-idlimit)
|
||||
* [Update limits](#update-limits)
|
||||
* [POST /api/projects/{project-id}/limit?usage={value}](#post-apiprojectsproject-idlimitusagevalue)
|
||||
* [POST /api/projects/{project-id}/limit?bandwidth={value}](#post-apiprojectsproject-idlimitbandwidthvalue)
|
||||
* [POST /api/projects/{project-id}/limit?rate={value}](#post-apiprojectsproject-idlimitratevalue)
|
||||
* [POST /api/projects/{project-id}/limit?buckets={value}](#post-apiprojectsproject-idlimitbucketsvalue)
|
||||
* [APIKey Management](#apikey-management)
|
||||
* [DELETE /api/apikeys/{apikey}](#delete-apiapikeysapikey)
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## User Management
|
||||
## API design
|
||||
|
||||
### POST /api/users
|
||||
### Error responses
|
||||
|
||||
When an API endpoint returns a client error (status code 4XX) it returns a JSON error response which contains 2 fields:
|
||||
|
||||
* `error`: The error message.
|
||||
* `detail` (may be empty): Some detail about the returned error.
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": "usage for the current month exists",
|
||||
"detail": ""
|
||||
}
|
||||
```
|
||||
|
||||
## API Endpoints
|
||||
### User Management
|
||||
|
||||
#### POST /api/users
|
||||
|
||||
Adds a new user.
|
||||
|
||||
@ -64,7 +86,7 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### PUT /api/users/{user-email}
|
||||
#### PUT /api/users/{user-email}
|
||||
|
||||
Updates the details of existing user found by its email.
|
||||
|
||||
@ -89,7 +111,7 @@ Some example request bodies:
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/users/{user-email}
|
||||
#### GET /api/users/{user-email}
|
||||
|
||||
This endpoint returns information about user and their projects.
|
||||
|
||||
@ -126,17 +148,17 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /api/users/{user-email}
|
||||
#### DELETE /api/users/{user-email}
|
||||
|
||||
Deletes the user.
|
||||
|
||||
## Coupon Management
|
||||
### Coupon Management
|
||||
|
||||
The coupons have an amount and duration.
|
||||
Amount is expressed in cents of USD dollars (e.g. 500 is $5)
|
||||
Duration is expressed in billing periods, a billing period is a natural month.
|
||||
|
||||
### POST /api/coupons
|
||||
#### POST /api/coupons
|
||||
|
||||
Adds a coupon for specific user.
|
||||
|
||||
@ -159,7 +181,7 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/coupons/{coupon-id}
|
||||
#### GET /api/coupons/{coupon-id}
|
||||
|
||||
Gets a coupon with the specified id.
|
||||
|
||||
@ -178,13 +200,13 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /api/coupons/{coupon-id}
|
||||
#### DELETE /api/coupons/{coupon-id}
|
||||
|
||||
Deletes the specified coupon.
|
||||
|
||||
## Project Management
|
||||
### Project Management
|
||||
|
||||
### POST /api/projects
|
||||
#### POST /api/projects
|
||||
|
||||
Adds a project for specific user.
|
||||
|
||||
@ -205,11 +227,11 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/projects/{project-id}
|
||||
#### GET /api/projects/{project-id}
|
||||
|
||||
Gets the common information about a project.
|
||||
|
||||
### PUT /api/projects/{project-id}
|
||||
#### PUT /api/projects/{project-id}
|
||||
|
||||
Updates project name or description.
|
||||
|
||||
@ -220,11 +242,11 @@ Updates project name or description.
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /api/projects/{project-id}
|
||||
#### DELETE /api/projects/{project-id}
|
||||
|
||||
Deletes the project.
|
||||
|
||||
### GET /api/projects/{project}/apikeys
|
||||
#### GET /api/projects/{project}/apikeys
|
||||
|
||||
Get the list of the API keys of a specific project.
|
||||
|
||||
@ -249,7 +271,7 @@ A successful response body:
|
||||
]
|
||||
```
|
||||
|
||||
### POST /api/projects/{project}/apikeys
|
||||
#### POST /api/projects/{project}/apikeys
|
||||
|
||||
Adds an apikey for specific project.
|
||||
|
||||
@ -271,17 +293,18 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### DELETE /api/projects/{project}/apikeys/{name}
|
||||
#### DELETE /api/projects/{project}/apikeys/{name}
|
||||
|
||||
Deletes the given apikey by its name.
|
||||
|
||||
### GET /api/projects/{project-id}/usage
|
||||
#### GET /api/projects/{project-id}/usage
|
||||
|
||||
This endpoint returns whether the project has outstanding usage or not.
|
||||
|
||||
A project with not usage returns status code 200 and `{"result":"no project usage exist"}`.
|
||||
Otherwise, it returns status code 409 with a JSON error.`{"error":"usage for current month exists""}`.
|
||||
|
||||
### GET /api/projects/{project-id}/limit
|
||||
#### GET /api/projects/{project-id}/limit
|
||||
|
||||
This endpoint returns information about project limits.
|
||||
|
||||
@ -303,29 +326,29 @@ A successful response body:
|
||||
}
|
||||
```
|
||||
|
||||
### Update limits
|
||||
#### Update limits
|
||||
|
||||
You can update the different limits with one single request just adding the
|
||||
various query parameters (e.g. `usage=5000000&bandwidth=9000000`)
|
||||
|
||||
#### POST /api/projects/{project-id}/limit?usage={value}
|
||||
##### POST /api/projects/{project-id}/limit?usage={value}
|
||||
|
||||
Updates usage limit for a project. The value must be in bytes.
|
||||
|
||||
#### POST /api/projects/{project-id}/limit?bandwidth={value}
|
||||
##### POST /api/projects/{project-id}/limit?bandwidth={value}
|
||||
|
||||
Updates bandwidth limit for a project. The value must be in bytes.
|
||||
|
||||
#### POST /api/projects/{project-id}/limit?rate={value}
|
||||
##### POST /api/projects/{project-id}/limit?rate={value}
|
||||
|
||||
Updates rate limit for a project.
|
||||
|
||||
#### POST /api/projects/{project-id}/limit?buckets={value}
|
||||
##### POST /api/projects/{project-id}/limit?buckets={value}
|
||||
|
||||
Updates bucket limit for a project.
|
||||
|
||||
## APIKey Management
|
||||
### APIKey Management
|
||||
|
||||
### DELETE /api/apikeys/{apikey}
|
||||
#### DELETE /api/apikeys/{apikey}
|
||||
|
||||
Deletes the given apikey.
|
||||
|
@ -29,7 +29,7 @@ func TestAddApiKey(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -49,6 +49,7 @@ func TestAddApiKey(t *testing.T) {
|
||||
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"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
@ -80,7 +81,7 @@ func TestDeleteApiKey(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -100,6 +101,7 @@ func TestDeleteApiKey(t *testing.T) {
|
||||
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())
|
||||
@ -117,7 +119,7 @@ func TestDeleteApiKeyByName(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -136,6 +138,7 @@ func TestDeleteApiKeyByName(t *testing.T) {
|
||||
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())
|
||||
@ -153,7 +156,7 @@ func TestListAPIKeys(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
|
@ -13,20 +13,25 @@ import (
|
||||
// Error is default error class for admin package.
|
||||
var Error = errs.Class("admin")
|
||||
|
||||
func httpJSONError(w http.ResponseWriter, error, detail string, statusCode int) {
|
||||
func httpJSONError(w http.ResponseWriter, errMsg, detail string, statusCode int) {
|
||||
errStr := struct {
|
||||
Error string `json:"error"`
|
||||
Detail string `json:"detail"`
|
||||
}{
|
||||
Error: error,
|
||||
Error: errMsg,
|
||||
Detail: detail,
|
||||
}
|
||||
byt, err := json.Marshal(errStr)
|
||||
body, err := json.Marshal(errStr)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(statusCode)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write(byt) // any error here entitles a client side disconnect or similar, which we do not care about.
|
||||
sendJSONData(w, statusCode, body)
|
||||
}
|
||||
|
||||
func sendJSONData(w http.ResponseWriter, statusCode int, data []byte) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(statusCode)
|
||||
_, _ = w.Write(data) // any error here entitles a client side disconnect or similar, which we do not care about.
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ func TestAddCoupon(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -44,6 +44,7 @@ func TestAddCoupon(t *testing.T) {
|
||||
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"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
@ -69,7 +70,7 @@ func TestCouponInfo(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -89,6 +90,7 @@ func TestCouponInfo(t *testing.T) {
|
||||
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"))
|
||||
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
@ -104,6 +106,7 @@ func TestCouponInfo(t *testing.T) {
|
||||
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"))
|
||||
|
||||
responseBody, err = ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
@ -125,7 +128,7 @@ func TestCouponDelete(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -144,6 +147,7 @@ func TestCouponDelete(t *testing.T) {
|
||||
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"))
|
||||
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
@ -165,6 +169,7 @@ func TestCouponDelete(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
|
||||
coupons, err = planet.Satellites[0].DB.StripeCoinPayments().Coupons().ListByUserID(ctx, user.ID)
|
||||
require.NoError(t, err)
|
||||
|
@ -32,7 +32,7 @@ func TestAPI(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -135,7 +135,7 @@ func TestAddProject(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -151,6 +151,7 @@ func TestAddProject(t *testing.T) {
|
||||
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"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
@ -174,7 +175,7 @@ func TestRenameProject(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -195,6 +196,7 @@ func TestRenameProject(t *testing.T) {
|
||||
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)
|
||||
@ -209,7 +211,7 @@ func TestDeleteProject(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -239,6 +241,7 @@ func TestDeleteProject(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusConflict, response.StatusCode)
|
||||
require.Equal(t, "application/json", response.Header.Get("Content-Type"))
|
||||
|
||||
err = planet.Satellites[0].DB.Console().APIKeys().Delete(ctx, apikeys.APIKeys[0].ID)
|
||||
require.NoError(t, err)
|
||||
@ -251,6 +254,7 @@ func TestDeleteProject(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
require.Equal(t, "", response.Header.Get("Content-Type"))
|
||||
|
||||
project, err := planet.Satellites[0].DB.Console().Projects().Get(ctx, projectID)
|
||||
require.Error(t, err)
|
||||
@ -264,7 +268,7 @@ func TestCheckUsageWithoutUsage(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -289,11 +293,12 @@ func TestCheckUsageWithoutUsage(t *testing.T) {
|
||||
|
||||
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"))
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "{\"result\":\"no project usage exist\"}", string(responseBody))
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusOK, response.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
@ -303,7 +308,7 @@ func TestCheckUsageWithUsage(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -353,11 +358,13 @@ func TestCheckUsageWithUsage(t *testing.T) {
|
||||
|
||||
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.Equal(t, "{\"error\":\"usage for current month exists\",\"detail\":\"\"}", string(responseBody))
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusConflict, response.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
@ -367,7 +374,7 @@ func TestCheckUsageLastMonthUnappliedInvoice(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -429,11 +436,13 @@ func TestCheckUsageLastMonthUnappliedInvoice(t *testing.T) {
|
||||
|
||||
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.Equal(t, "{\"error\":\"unapplied project invoice record exist\",\"detail\":\"\"}", string(responseBody))
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusConflict, response.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
@ -443,7 +452,7 @@ func TestDeleteProjectWithUsageCurrentMonth(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -493,11 +502,13 @@ func TestDeleteProjectWithUsageCurrentMonth(t *testing.T) {
|
||||
|
||||
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.Equal(t, "{\"error\":\"usage for current month exists\",\"detail\":\"\"}", string(responseBody))
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.Equal(t, http.StatusConflict, response.StatusCode)
|
||||
})
|
||||
}
|
||||
|
||||
@ -507,7 +518,7 @@ func TestDeleteProjectWithUsagePreviousMonth(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
|
@ -4,6 +4,7 @@
|
||||
package admin_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
@ -37,7 +38,12 @@ func TestBasic(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, http.StatusForbidden, response.StatusCode)
|
||||
require.Equal(t, "application/json", response.Header.Get("Content-Type"))
|
||||
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, `{"error":"Forbidden","detail":""}`, string(body))
|
||||
})
|
||||
|
||||
t.Run("WrongAccess", func(t *testing.T) {
|
||||
@ -49,7 +55,12 @@ func TestBasic(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, http.StatusForbidden, response.StatusCode)
|
||||
require.Equal(t, "application/json", response.Header.Get("Content-Type"))
|
||||
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, `{"error":"Forbidden","detail":""}`, string(body))
|
||||
})
|
||||
|
||||
t.Run("WithAccess", func(t *testing.T) {
|
||||
@ -62,7 +73,12 @@ func TestBasic(t *testing.T) {
|
||||
|
||||
// currently no main page so 404
|
||||
require.Equal(t, http.StatusNotFound, response.StatusCode)
|
||||
require.Equal(t, "text/plain; charset=utf-8", response.Header.Get("Content-Type"))
|
||||
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, response.Body.Close())
|
||||
require.NoError(t, err)
|
||||
require.Contains(t, string(body), "not found")
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -67,5 +67,11 @@ func assertReq(
|
||||
require.Equal(t, expectedBody, string(resBody), "response body")
|
||||
}
|
||||
|
||||
if len(resBody) > 0 {
|
||||
require.Equal(t, "application/json", res.Header.Get("Content-Type"))
|
||||
} else {
|
||||
require.Equal(t, "", res.Header.Get("Content-Type"))
|
||||
}
|
||||
|
||||
return resBody
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ func TestGetUser(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -58,6 +58,8 @@ func TestGetUser(t *testing.T) {
|
||||
|
||||
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)
|
||||
@ -75,7 +77,7 @@ func TestAddUser(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -91,6 +93,8 @@ func TestAddUser(t *testing.T) {
|
||||
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"))
|
||||
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
@ -112,7 +116,7 @@ func TestAddUserSameEmail(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -128,6 +132,8 @@ func TestAddUserSameEmail(t *testing.T) {
|
||||
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"))
|
||||
|
||||
responseBody, err := ioutil.ReadAll(response.Body)
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, response.Body.Close())
|
||||
@ -150,6 +156,7 @@ func TestAddUserSameEmail(t *testing.T) {
|
||||
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"))
|
||||
require.NoError(t, response.Body.Close())
|
||||
})
|
||||
}
|
||||
@ -160,7 +167,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -177,6 +184,7 @@ func TestUpdateUser(t *testing.T) {
|
||||
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())
|
||||
@ -200,7 +208,7 @@ func TestUpdateUserRateLimit(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -219,6 +227,7 @@ func TestUpdateUserRateLimit(t *testing.T) {
|
||||
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())
|
||||
@ -239,7 +248,7 @@ func TestDeleteUser(t *testing.T) {
|
||||
StorageNodeCount: 0,
|
||||
UplinkCount: 1,
|
||||
Reconfigure: testplanet.Reconfigure{
|
||||
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
|
||||
Satellite: func(_ *zap.Logger, _ int, config *satellite.Config) {
|
||||
config.Admin.Address = "127.0.0.1:0"
|
||||
},
|
||||
},
|
||||
@ -256,6 +265,7 @@ func TestDeleteUser(t *testing.T) {
|
||||
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())
|
||||
@ -272,6 +282,7 @@ func TestDeleteUser(t *testing.T) {
|
||||
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())
|
||||
|
Loading…
Reference in New Issue
Block a user