mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-26 01:53:42 +01:00
59372ee159
removed all PATCH endpoints updated path parameters for all endpoints removed not implemented endpoints for api doc minor description updates
274 lines
7.1 KiB
Go
274 lines
7.1 KiB
Go
package http
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/netbirdio/netbird/management/server/http/api"
|
|
"github.com/netbirdio/netbird/management/server/status"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/netbirdio/netbird/management/server/jwtclaims"
|
|
|
|
"github.com/magiconair/properties/assert"
|
|
|
|
"github.com/netbirdio/netbird/management/server"
|
|
"github.com/netbirdio/netbird/management/server/mock_server"
|
|
)
|
|
|
|
var TestPeers = map[string]*server.Peer{
|
|
"A": {Key: "A", ID: "peer-A-ID", IP: net.ParseIP("100.100.100.100")},
|
|
"B": {Key: "B", ID: "peer-B-ID", IP: net.ParseIP("200.200.200.200")},
|
|
}
|
|
|
|
func initGroupTestData(user *server.User, groups ...*server.Group) *GroupsHandler {
|
|
return &GroupsHandler{
|
|
accountManager: &mock_server.MockAccountManager{
|
|
SaveGroupFunc: func(accountID, userID string, group *server.Group) error {
|
|
if !strings.HasPrefix(group.ID, "id-") {
|
|
group.ID = "id-was-set"
|
|
}
|
|
return nil
|
|
},
|
|
GetGroupFunc: func(_, groupID string) (*server.Group, error) {
|
|
if groupID != "idofthegroup" {
|
|
return nil, status.Errorf(status.NotFound, "not found")
|
|
}
|
|
return &server.Group{
|
|
ID: "idofthegroup",
|
|
Name: "Group",
|
|
}, nil
|
|
},
|
|
UpdateGroupFunc: func(_ string, groupID string, operations []server.GroupUpdateOperation) (*server.Group, error) {
|
|
var group server.Group
|
|
group.ID = groupID
|
|
for _, operation := range operations {
|
|
switch operation.Type {
|
|
case server.UpdateGroupName:
|
|
group.Name = operation.Values[0]
|
|
case server.UpdateGroupPeers, server.InsertPeersToGroup:
|
|
group.Peers = operation.Values
|
|
case server.RemovePeersFromGroup:
|
|
default:
|
|
return nil, fmt.Errorf("no operation")
|
|
}
|
|
}
|
|
return &group, nil
|
|
},
|
|
GetPeerByIPFunc: func(_ string, peerIP string) (*server.Peer, error) {
|
|
for _, peer := range TestPeers {
|
|
if peer.IP.String() == peerIP {
|
|
return peer, nil
|
|
}
|
|
}
|
|
return nil, fmt.Errorf("peer not found")
|
|
},
|
|
GetAccountFromTokenFunc: func(claims jwtclaims.AuthorizationClaims) (*server.Account, *server.User, error) {
|
|
return &server.Account{
|
|
Id: claims.AccountId,
|
|
Domain: "hotmail.com",
|
|
Peers: TestPeers,
|
|
Users: map[string]*server.User{
|
|
user.Id: user,
|
|
},
|
|
Groups: map[string]*server.Group{
|
|
"id-existed": {ID: "id-existed", Peers: []string{"A", "B"}},
|
|
"id-all": {ID: "id-all", Name: "All"},
|
|
},
|
|
}, user, nil
|
|
},
|
|
},
|
|
claimsExtractor: jwtclaims.NewClaimsExtractor(
|
|
jwtclaims.WithFromRequestContext(func(r *http.Request) jwtclaims.AuthorizationClaims {
|
|
return jwtclaims.AuthorizationClaims{
|
|
UserId: "test_user",
|
|
Domain: "hotmail.com",
|
|
AccountId: "test_id",
|
|
}
|
|
}),
|
|
),
|
|
}
|
|
}
|
|
|
|
func TestGetGroup(t *testing.T) {
|
|
tt := []struct {
|
|
name string
|
|
expectedStatus int
|
|
expectedBody bool
|
|
requestType string
|
|
requestPath string
|
|
requestBody io.Reader
|
|
}{
|
|
{
|
|
name: "GetGroup OK",
|
|
expectedBody: true,
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/groups/idofthegroup",
|
|
expectedStatus: http.StatusOK,
|
|
},
|
|
{
|
|
name: "GetGroup not found",
|
|
requestType: http.MethodGet,
|
|
requestPath: "/api/groups/notexists",
|
|
expectedStatus: http.StatusNotFound,
|
|
},
|
|
}
|
|
|
|
group := &server.Group{
|
|
ID: "idofthegroup",
|
|
Name: "Group",
|
|
}
|
|
|
|
adminUser := server.NewAdminUser("test_user")
|
|
p := initGroupTestData(adminUser, group)
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
req := httptest.NewRequest(tc.requestType, tc.requestPath, tc.requestBody)
|
|
|
|
router := mux.NewRouter()
|
|
router.HandleFunc("/api/groups/{groupId}", p.GetGroup).Methods("GET")
|
|
router.ServeHTTP(recorder, req)
|
|
|
|
res := recorder.Result()
|
|
defer res.Body.Close()
|
|
|
|
if status := recorder.Code; status != tc.expectedStatus {
|
|
t.Errorf("handler returned wrong status code: got %v want %v",
|
|
status, tc.expectedStatus)
|
|
return
|
|
}
|
|
|
|
if !tc.expectedBody {
|
|
return
|
|
}
|
|
|
|
content, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
t.Fatalf("I don't know what I expected; %v", err)
|
|
}
|
|
|
|
got := &server.Group{}
|
|
if err = json.Unmarshal(content, &got); err != nil {
|
|
t.Fatalf("Sent content is not in correct json format; %v", err)
|
|
}
|
|
|
|
assert.Equal(t, got.ID, group.ID)
|
|
assert.Equal(t, got.Name, group.Name)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestWriteGroup(t *testing.T) {
|
|
tt := []struct {
|
|
name string
|
|
expectedStatus int
|
|
expectedBody bool
|
|
expectedGroup *api.Group
|
|
requestType string
|
|
requestPath string
|
|
requestBody io.Reader
|
|
}{
|
|
{
|
|
name: "Write Group POST OK",
|
|
requestType: http.MethodPost,
|
|
requestPath: "/api/groups",
|
|
requestBody: bytes.NewBuffer(
|
|
[]byte(`{"Name":"Default POSTed Group"}`)),
|
|
expectedStatus: http.StatusOK,
|
|
expectedBody: true,
|
|
expectedGroup: &api.Group{
|
|
Id: "id-was-set",
|
|
Name: "Default POSTed Group",
|
|
},
|
|
},
|
|
{
|
|
name: "Write Group POST Invalid Name",
|
|
requestType: http.MethodPost,
|
|
requestPath: "/api/groups",
|
|
requestBody: bytes.NewBuffer(
|
|
[]byte(`{"name":""}`)),
|
|
expectedStatus: http.StatusUnprocessableEntity,
|
|
expectedBody: false,
|
|
},
|
|
{
|
|
name: "Write Group PUT OK",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/groups/id-existed",
|
|
requestBody: bytes.NewBuffer(
|
|
[]byte(`{"Name":"Default POSTed Group"}`)),
|
|
expectedStatus: http.StatusOK,
|
|
expectedGroup: &api.Group{
|
|
Id: "id-existed",
|
|
Name: "Default POSTed Group",
|
|
},
|
|
},
|
|
{
|
|
name: "Write Group PUT Invalid Name",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/groups/id-existed",
|
|
requestBody: bytes.NewBuffer(
|
|
[]byte(`{"Name":""}`)),
|
|
expectedStatus: http.StatusUnprocessableEntity,
|
|
expectedBody: false,
|
|
},
|
|
{
|
|
name: "Write Group PUT All Group Name",
|
|
requestType: http.MethodPut,
|
|
requestPath: "/api/groups/id-all",
|
|
requestBody: bytes.NewBuffer(
|
|
[]byte(`{"Name":"super"}`)),
|
|
expectedStatus: http.StatusUnprocessableEntity,
|
|
expectedBody: false,
|
|
},
|
|
}
|
|
|
|
adminUser := server.NewAdminUser("test_user")
|
|
p := initGroupTestData(adminUser)
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
req := httptest.NewRequest(tc.requestType, tc.requestPath, tc.requestBody)
|
|
|
|
router := mux.NewRouter()
|
|
router.HandleFunc("/api/groups", p.CreateGroup).Methods("POST")
|
|
router.HandleFunc("/api/groups/{groupId}", p.UpdateGroup).Methods("PUT")
|
|
router.ServeHTTP(recorder, req)
|
|
|
|
res := recorder.Result()
|
|
defer res.Body.Close()
|
|
|
|
content, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
t.Fatalf("I don't know what I expected; %v", err)
|
|
}
|
|
|
|
if status := recorder.Code; status != tc.expectedStatus {
|
|
t.Errorf("handler returned wrong status code: got %v want %v, content: %s",
|
|
status, tc.expectedStatus, string(content))
|
|
return
|
|
}
|
|
|
|
if !tc.expectedBody {
|
|
return
|
|
}
|
|
|
|
got := &api.Group{}
|
|
if err = json.Unmarshal(content, &got); err != nil {
|
|
t.Fatalf("Sent content is not in correct json format; %v", err)
|
|
}
|
|
assert.Equal(t, got, tc.expectedGroup)
|
|
})
|
|
}
|
|
}
|