Commit a319c94b authored by ale's avatar ale
Browse files

Add tests for errors returned by the HTTP API

parent b590bd1e
Pipeline #24837 passed with stages
in 3 minutes and 14 seconds
package integrationtest
import (
"encoding/json"
"errors"
"net/http"
"testing"
as "git.autistici.org/ai3/accountserver"
)
func TestIntegration_Error_GetUser(t *testing.T) {
stop, _, c := startService(t)
defer stop()
testdata := []struct {
reqUser string
authUser string
authGroup string
expectedErrCode int
}{
{"uno@investici.org", "due@investici.org", "", http.StatusForbidden},
{"zero@investici.org", testAdminUser, testAdminGroup, http.StatusNotFound},
{"", testAdminUser, testAdminGroup, http.StatusNotFound},
}
for _, td := range testdata {
var user as.User
var groups []string
if td.authGroup != "" {
groups = append(groups, td.authGroup)
}
err := c.request("/api/user/get", &as.GetUserRequest{
UserRequestBase: as.UserRequestBase{
RequestBase: as.RequestBase{
SSO: c.ssoTicket(td.authUser, groups...),
},
Username: td.reqUser,
},
}, &user)
if err == nil {
t.Errorf("oops, request for %s as %s succeeded unexpectedly", td.reqUser, td.authUser)
continue
}
var httpErr *httpError
if !errors.As(err, &httpErr) {
t.Errorf("oops, request for %s as %s returned unexpected error: %v", td.reqUser, td.authUser, err)
continue
}
if httpErr.code != td.expectedErrCode {
t.Errorf("request for %s as %s returned error code %d, expected %d", td.reqUser, td.authUser, httpErr.code, td.expectedErrCode)
}
}
}
func TestIntegration_Error_Validation(t *testing.T) {
stop, _, c := startService(t)
defer stop()
var resp as.CreateUserResponse
err := c.request("/api/user/create", &as.CreateUserRequest{
AdminRequestBase: as.AdminRequestBase{
RequestBase: as.RequestBase{
SSO: c.ssoTicket(testAdminUser),
},
},
User: &as.User{
Name: "%@example.com",
Resources: []*as.Resource{
&as.Resource{
Type: as.ResourceTypeEmail,
Name: "%@example.com",
},
},
},
}, &resp)
if err == nil {
t.Fatal("CreateUser() succeeded unexpectedly")
}
var httpErr *httpError
if !errors.As(err, &httpErr) {
t.Fatalf("CreateUser() did not return a structured error: %v", err)
}
var fields map[string][]string
if err := json.Unmarshal(httpErr.data, &fields); err != nil {
t.Fatalf("error unmarshaling JSON error: %v", err)
}
if values, ok := fields["name"]; !ok || len(values) != 1 {
t.Fatalf("error does not contain details for the 'name' field: %+v", fields)
}
}
......@@ -4,7 +4,6 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
......@@ -116,6 +115,15 @@ func (c *testClient) ssoTicket(username string, groups ...string) string {
return signed
}
type httpError struct {
code int
data []byte
}
func (e *httpError) Error() string {
return fmt.Sprintf("HTTP status %d", e.code)
}
func (c *testClient) request(uri string, req, out interface{}) error {
data, _ := json.Marshal(req)
resp, err := http.Post(c.srvURL+uri, "application/json", bytes.NewReader(data))
......@@ -127,11 +135,11 @@ func (c *testClient) request(uri string, req, out interface{}) error {
if resp.StatusCode >= 400 && resp.StatusCode < 500 {
log.Printf("request error: %s", string(data))
return errors.New(string(data))
return &httpError{code: resp.StatusCode, data: data}
}
if resp.StatusCode != 200 {
log.Printf("remote error: %s", string(data))
return fmt.Errorf("http status code %d", resp.StatusCode)
return &httpError{code: resp.StatusCode, data: data}
}
if resp.Header.Get("Content-Type") != "application/json" {
return fmt.Errorf("unexpected content-type %s", resp.Header.Get("Content-Type"))
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment