influxdb/chronograf/enterprise/meta_test.go

1499 lines
34 KiB
Go

package enterprise
import (
"bytes"
"context"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"reflect"
"testing"
"time"
"github.com/influxdata/influxdb/v2/chronograf/influx"
)
func TestMetaClient_ShowCluster(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
tests := []struct {
name string
fields fields
want *Cluster
wantErr bool
}{
{
name: "Successful Show Cluster",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"data":[{"id":2,"version":"1.1.0-c1.1.0","tcpAddr":"data-1.twinpinesmall.net:8088","httpAddr":"data-1.twinpinesmall.net:8086","httpScheme":"https","status":"joined"}],"meta":[{"id":1,"addr":"meta-0.twinpinesmall.net:8091","httpScheme":"http","tcpAddr":"meta-0.twinpinesmall.net:8089","version":"1.1.0-c1.1.0"}]}`),
nil,
nil,
),
},
want: &Cluster{
DataNodes: []DataNode{
{
ID: 2,
TCPAddr: "data-1.twinpinesmall.net:8088",
HTTPAddr: "data-1.twinpinesmall.net:8086",
HTTPScheme: "https",
Status: "joined",
},
},
MetaNodes: []Node{
{
ID: 1,
Addr: "meta-0.twinpinesmall.net:8091",
HTTPScheme: "http",
TCPAddr: "meta-0.twinpinesmall.net:8089",
},
},
},
},
{
name: "Failed Show Cluster",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusBadGateway,
nil,
nil,
fmt.Errorf("time circuits on. Flux Capacitor... fluxxing"),
),
},
wantErr: true,
},
{
name: "Bad JSON from Show Cluster",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{data}`),
nil,
nil,
),
},
wantErr: true,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
got, err := m.ShowCluster(context.Background())
if (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.ShowCluster() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. MetaClient.ShowCluster() = %v, want %v", tt.name, got, tt.want)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) != 1 {
t.Errorf("%q. MetaClient.ShowCluster() expected 1 but got %d", tt.name, len(reqs))
continue
}
req := reqs[0]
if req.Method != "GET" {
t.Errorf("%q. MetaClient.ShowCluster() expected GET method", tt.name)
}
if req.URL.Path != "/show-cluster" {
t.Errorf("%q. MetaClient.ShowCluster() expected /show-cluster path but got %s", tt.name, req.URL.Path)
}
}
}
func TestMetaClient_Users(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name *string
}
tests := []struct {
name string
fields fields
args args
want *Users
wantErr bool
}{
{
name: "Successful Show users",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"users":[{"name":"admin","hash":"1234","permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: nil,
},
want: &Users{
Users: []User{
{
Name: "admin",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
},
},
},
},
{
name: "Successful Show users single user",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"users":[{"name":"admin","hash":"1234","permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: &[]string{"admin"}[0],
},
want: &Users{
Users: []User{
{
Name: "admin",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
},
},
},
},
{
name: "Failure Show users",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"users":[{"name":"admin","hash":"1234","permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
fmt.Errorf("time circuits on. Flux Capacitor... fluxxing"),
),
},
args: args{
ctx: context.Background(),
name: nil,
},
wantErr: true,
},
{
name: "Bad JSON from Show users",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{foo}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: nil,
},
wantErr: true,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
got, err := m.Users(tt.args.ctx, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.Users() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. MetaClient.Users() = %v, want %v", tt.name, got, tt.want)
}
}
}
func TestMetaClient_User(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
}
tests := []struct {
name string
fields fields
args args
want *User
wantErr bool
}{
{
name: "Successful Show users",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"users":[{"name":"admin","hash":"1234","permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
want: &User{
Name: "admin",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
},
},
{
name: "No such user",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusNotFound,
[]byte(`{"error":"user not found"}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "unknown",
},
wantErr: true,
},
{
name: "Bad JSON",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusNotFound,
[]byte(`{BAD}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
},
wantErr: true,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
got, err := m.User(tt.args.ctx, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.User() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. MetaClient.User() = %v, want %v", tt.name, got, tt.want)
}
}
}
func TestMetaClient_CreateUser(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
passwd string
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
}{
{
name: "Successful Create User",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
nil,
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
passwd: "hunter2",
},
want: `{"action":"create","user":{"name":"admin","password":"hunter2"}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.CreateUser(tt.args.ctx, tt.args.name, tt.args.passwd); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.CreateUser() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) != 1 {
t.Errorf("%q. MetaClient.CreateUser() expected 1 but got %d", tt.name, len(reqs))
continue
}
req := reqs[0]
if req.Method != "POST" {
t.Errorf("%q. MetaClient.CreateUser() expected POST method", tt.name)
}
if req.URL.Path != "/user" {
t.Errorf("%q. MetaClient.CreateUser() expected /user path but got %s", tt.name, req.URL.Path)
}
got, _ := ioutil.ReadAll(req.Body)
if string(got) != tt.want {
t.Errorf("%q. MetaClient.CreateUser() = %v, want %v", tt.name, string(got), tt.want)
}
}
}
func TestMetaClient_ChangePassword(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
passwd string
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
}{
{
name: "Successful Change Password",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
nil,
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
passwd: "hunter2",
},
want: `{"action":"change-password","user":{"name":"admin","password":"hunter2"}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.ChangePassword(tt.args.ctx, tt.args.name, tt.args.passwd); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.ChangePassword() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) != 1 {
t.Errorf("%q. MetaClient.ChangePassword() expected 1 but got %d", tt.name, len(reqs))
continue
}
req := reqs[0]
if req.Method != "POST" {
t.Errorf("%q. MetaClient.ChangePassword() expected POST method", tt.name)
}
if req.URL.Path != "/user" {
t.Errorf("%q. MetaClient.ChangePassword() expected /user path but got %s", tt.name, req.URL.Path)
}
got, _ := ioutil.ReadAll(req.Body)
if string(got) != tt.want {
t.Errorf("%q. MetaClient.ChangePassword() = %v, want %v", tt.name, string(got), tt.want)
}
}
}
func TestMetaClient_DeleteUser(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
}{
{
name: "Successful delete User",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
nil,
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
want: `{"action":"delete","user":{"name":"admin"}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.DeleteUser(tt.args.ctx, tt.args.name); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.DeleteUser() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) != 1 {
t.Errorf("%q. MetaClient.DeleteUser() expected 1 but got %d", tt.name, len(reqs))
continue
}
req := reqs[0]
if req.Method != "POST" {
t.Errorf("%q. MetaClient.DeleteUser() expected POST method", tt.name)
}
if req.URL.Path != "/user" {
t.Errorf("%q. MetaClient.DeleteUser() expected /user path but got %s", tt.name, req.URL.Path)
}
got, _ := ioutil.ReadAll(req.Body)
if string(got) != tt.want {
t.Errorf("%q. MetaClient.DeleteUser() = %v, want %v", tt.name, string(got), tt.want)
}
}
}
func TestMetaClient_SetUserPerms(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
perms Permissions
}
tests := []struct {
name string
fields fields
args args
wantRm string
wantAdd string
wantErr bool
}{
{
name: "Remove all permissions for a user",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"users":[{"name":"admin","hash":"1234","permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
wantRm: `{"action":"remove-permissions","user":{"name":"admin","permissions":{"":["ViewAdmin","ViewChronograf"]}}}`,
},
{
name: "Remove some permissions and add others",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"users":[{"name":"admin","hash":"1234","permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
perms: Permissions{
"telegraf": []string{
"ReadData",
},
},
},
wantRm: `{"action":"remove-permissions","user":{"name":"admin","permissions":{"":["ViewAdmin","ViewChronograf"]}}}`,
wantAdd: `{"action":"add-permissions","user":{"name":"admin","permissions":{"telegraf":["ReadData"]}}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.SetUserPerms(tt.args.ctx, tt.args.name, tt.args.perms); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.SetUserPerms() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) < 2 {
t.Errorf("%q. MetaClient.SetUserPerms() expected 2 but got %d", tt.name, len(reqs))
continue
}
usr := reqs[0]
if usr.Method != "GET" {
t.Errorf("%q. MetaClient.SetUserPerms() expected GET method", tt.name)
}
if usr.URL.Path != "/user" {
t.Errorf("%q. MetaClient.SetUserPerms() expected /user path but got %s", tt.name, usr.URL.Path)
}
prm := reqs[1]
if prm.Method != "POST" {
t.Errorf("%q. MetaClient.SetUserPerms() expected GET method", tt.name)
}
if prm.URL.Path != "/user" {
t.Errorf("%q. MetaClient.SetUserPerms() expected /user path but got %s", tt.name, prm.URL.Path)
}
got, _ := ioutil.ReadAll(prm.Body)
if string(got) != tt.wantRm {
t.Errorf("%q. MetaClient.SetUserPerms() = %v, want %v", tt.name, string(got), tt.wantRm)
}
if tt.wantAdd != "" {
prm := reqs[2]
if prm.Method != "POST" {
t.Errorf("%q. MetaClient.SetUserPerms() expected GET method", tt.name)
}
if prm.URL.Path != "/user" {
t.Errorf("%q. MetaClient.SetUserPerms() expected /user path but got %s", tt.name, prm.URL.Path)
}
got, _ := ioutil.ReadAll(prm.Body)
if string(got) != tt.wantAdd {
t.Errorf("%q. MetaClient.SetUserPerms() = %v, want %v", tt.name, string(got), tt.wantAdd)
}
}
}
}
func TestMetaClient_Roles(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name *string
}
tests := []struct {
name string
fields fields
args args
want *Roles
wantErr bool
}{
{
name: "Successful Show role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":["marty"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: nil,
},
want: &Roles{
Roles: []Role{
{
Name: "admin",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty"},
},
},
},
},
{
name: "Successful Show role single role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":["marty"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: &[]string{"admin"}[0],
},
want: &Roles{
Roles: []Role{
{
Name: "admin",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty"},
},
},
},
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
got, err := m.Roles(tt.args.ctx, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.Roles() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. MetaClient.Roles() = %v, want %v", tt.name, got, tt.want)
}
}
}
func TestMetaClient_Role(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
}
tests := []struct {
name string
fields fields
args args
want *Role
wantErr bool
}{
{
name: "Successful Show role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":["marty"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
want: &Role{
Name: "admin",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty"},
},
},
{
name: "No such role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusNotFound,
[]byte(`{"error":"user not found"}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "unknown",
},
wantErr: true,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
got, err := m.Role(tt.args.ctx, tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.Role() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. MetaClient.Role() = %v, want %v", tt.name, got, tt.want)
}
}
}
func TestMetaClient_UserRoles(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name *string
}
tests := []struct {
name string
fields fields
args args
want map[string]Roles
wantErr bool
}{
{
name: "Successful Show all roles",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"timetravelers","users":["marty","docbrown"],"permissions":{"":["ViewAdmin","ViewChronograf"]}},{"name":"mcfly","users":["marty","george"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: nil,
},
want: map[string]Roles{
"marty": Roles{
Roles: []Role{
{
Name: "timetravelers",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty", "docbrown"},
},
{
Name: "mcfly",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty", "george"},
},
},
},
"docbrown": Roles{
Roles: []Role{
{
Name: "timetravelers",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty", "docbrown"},
},
},
},
"george": Roles{
Roles: []Role{
{
Name: "mcfly",
Permissions: map[string][]string{
"": []string{
"ViewAdmin", "ViewChronograf",
},
},
Users: []string{"marty", "george"},
},
},
},
},
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
got, err := m.UserRoles(tt.args.ctx)
if (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.UserRoles() error = %v, wantErr %v", tt.name, err, tt.wantErr)
continue
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("%q. MetaClient.UserRoles() = %v, want %v", tt.name, got, tt.want)
}
}
}
func TestMetaClient_CreateRole(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
}{
{
name: "Successful Create Role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
nil,
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
want: `{"action":"create","role":{"name":"admin"}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.CreateRole(tt.args.ctx, tt.args.name); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.CreateRole() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
reqs := tt.fields.client.Requests
if len(reqs) != 1 {
t.Errorf("%q. MetaClient.CreateRole() expected 1 but got %d", tt.name, len(reqs))
continue
}
req := reqs[0]
if req.Method != "POST" {
t.Errorf("%q. MetaClient.CreateRole() expected POST method", tt.name)
}
if req.URL.Path != "/role" {
t.Errorf("%q. MetaClient.CreateRole() expected /role path but got %s", tt.name, req.URL.Path)
}
got, _ := ioutil.ReadAll(req.Body)
if string(got) != tt.want {
t.Errorf("%q. MetaClient.CreateRole() = %v, want %v", tt.name, string(got), tt.want)
}
}
}
func TestMetaClient_DeleteRole(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
}{
{
name: "Successful delete role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
nil,
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
want: `{"action":"delete","role":{"name":"admin"}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.DeleteRole(tt.args.ctx, tt.args.name); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.DeleteRole() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) != 1 {
t.Errorf("%q. MetaClient.DeleteRole() expected 1 but got %d", tt.name, len(reqs))
continue
}
req := reqs[0]
if req.Method != "POST" {
t.Errorf("%q. MetaClient.DeleDeleteRoleteUser() expected POST method", tt.name)
}
if req.URL.Path != "/role" {
t.Errorf("%q. MetaClient.DeleteRole() expected /role path but got %s", tt.name, req.URL.Path)
}
got, _ := ioutil.ReadAll(req.Body)
if string(got) != tt.want {
t.Errorf("%q. MetaClient.DeleteRole() = %v, want %v", tt.name, string(got), tt.want)
}
}
}
func TestMetaClient_SetRolePerms(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
perms Permissions
}
tests := []struct {
name string
fields fields
args args
wantRm string
wantAdd string
wantErr bool
}{
{
name: "Remove all roles from user",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":["marty"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
wantRm: `{"action":"remove-permissions","role":{"name":"admin","permissions":{"":["ViewAdmin","ViewChronograf"]}}}`,
},
{
name: "Remove some users and add permissions to other",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":["marty"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
perms: Permissions{
"telegraf": []string{
"ReadData",
},
},
},
wantRm: `{"action":"remove-permissions","role":{"name":"admin","permissions":{"":["ViewAdmin","ViewChronograf"]}}}`,
wantAdd: `{"action":"add-permissions","role":{"name":"admin","permissions":{"telegraf":["ReadData"]}}}`,
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.SetRolePerms(tt.args.ctx, tt.args.name, tt.args.perms); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.SetRolePerms() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) < 2 {
t.Errorf("%q. MetaClient.SetRolePerms() expected 2 but got %d", tt.name, len(reqs))
continue
}
usr := reqs[0]
if usr.Method != "GET" {
t.Errorf("%q. MetaClient.SetRolePerms() expected GET method", tt.name)
}
if usr.URL.Path != "/role" {
t.Errorf("%q. MetaClient.SetRolePerms() expected /user path but got %s", tt.name, usr.URL.Path)
}
prm := reqs[1]
if prm.Method != "POST" {
t.Errorf("%q. MetaClient.SetRolePerms() expected GET method", tt.name)
}
if prm.URL.Path != "/role" {
t.Errorf("%q. MetaClient.SetRolePerms() expected /role path but got %s", tt.name, prm.URL.Path)
}
got, _ := ioutil.ReadAll(prm.Body)
if string(got) != tt.wantRm {
t.Errorf("%q. MetaClient.SetRolePerms() removal = \n%v\n, want \n%v\n", tt.name, string(got), tt.wantRm)
}
if tt.wantAdd != "" {
prm := reqs[2]
if prm.Method != "POST" {
t.Errorf("%q. MetaClient.SetRolePerms() expected GET method", tt.name)
}
if prm.URL.Path != "/role" {
t.Errorf("%q. MetaClient.SetRolePerms() expected /role path but got %s", tt.name, prm.URL.Path)
}
got, _ := ioutil.ReadAll(prm.Body)
if string(got) != tt.wantAdd {
t.Errorf("%q. MetaClient.SetRolePerms() addition = \n%v\n, want \n%v\n", tt.name, string(got), tt.wantAdd)
}
}
}
}
func TestMetaClient_SetRoleUsers(t *testing.T) {
type fields struct {
URL *url.URL
client *MockClient
}
type args struct {
ctx context.Context
name string
users []string
}
tests := []struct {
name string
fields fields
args args
wants []string
wantErr bool
}{
{
name: "Successful set users role (remove user from role)",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":["marty"],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
},
wants: []string{`{"action":"remove-users","role":{"name":"admin","users":["marty"]}}`},
},
{
name: "Successful set single user role",
fields: fields{
URL: &url.URL{
Host: "twinpinesmall.net:8091",
Scheme: "https",
},
client: NewMockClient(
http.StatusOK,
[]byte(`{"roles":[{"name":"admin","users":[],"permissions":{"":["ViewAdmin","ViewChronograf"]}}]}`),
nil,
nil,
),
},
args: args{
ctx: context.Background(),
name: "admin",
users: []string{"marty"},
},
wants: []string{
`{"action":"add-users","role":{"name":"admin","users":["marty"]}}`,
},
},
}
for _, tt := range tests {
m := &MetaClient{
URL: tt.fields.URL,
client: tt.fields.client,
}
if err := m.SetRoleUsers(tt.args.ctx, tt.args.name, tt.args.users); (err != nil) != tt.wantErr {
t.Errorf("%q. MetaClient.SetRoleUsers() error = %v, wantErr %v", tt.name, err, tt.wantErr)
}
if tt.wantErr {
continue
}
reqs := tt.fields.client.Requests
if len(reqs) != len(tt.wants)+1 {
t.Errorf("%q. MetaClient.SetRoleUsers() expected %d but got %d", tt.name, len(tt.wants)+1, len(reqs))
continue
}
usr := reqs[0]
if usr.Method != "GET" {
t.Errorf("%q. MetaClient.SetRoleUsers() expected GET method", tt.name)
}
if usr.URL.Path != "/role" {
t.Errorf("%q. MetaClient.SetRoleUsers() expected /user path but got %s", tt.name, usr.URL.Path)
}
for i := range tt.wants {
prm := reqs[i+1]
if prm.Method != "POST" {
t.Errorf("%q. MetaClient.SetRoleUsers() expected GET method", tt.name)
}
if prm.URL.Path != "/role" {
t.Errorf("%q. MetaClient.SetRoleUsers() expected /role path but got %s", tt.name, prm.URL.Path)
}
got, _ := ioutil.ReadAll(prm.Body)
if string(got) != tt.wants[i] {
t.Errorf("%q. MetaClient.SetRoleUsers() = %v, want %v", tt.name, string(got), tt.wants[i])
}
}
}
}
type MockClient struct {
Code int // HTTP Status code
Body []byte
HeaderMap http.Header
Err error
Requests []*http.Request
}
func NewMockClient(code int, body []byte, headers http.Header, err error) *MockClient {
return &MockClient{
Code: code,
Body: body,
HeaderMap: headers,
Err: err,
Requests: make([]*http.Request, 0),
}
}
func (c *MockClient) Do(URL *url.URL, path, method string, authorizer influx.Authorizer, params map[string]string, body io.Reader) (*http.Response, error) {
if c == nil {
return nil, fmt.Errorf("nil MockClient")
}
if URL == nil {
return nil, fmt.Errorf("nil url")
}
if c.Err != nil {
return nil, c.Err
}
// Record the request in the mock client
p := url.Values{}
for k, v := range params {
p.Add(k, v)
}
URL.Path = path
URL.RawQuery = p.Encode()
req, err := http.NewRequest(method, URL.String(), body)
if err != nil {
return nil, err
}
c.Requests = append(c.Requests, req)
return &http.Response{
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
StatusCode: c.Code,
Status: http.StatusText(c.Code),
Header: c.HeaderMap,
Body: ioutil.NopCloser(bytes.NewReader(c.Body)),
}, nil
}
func Test_AuthedCheckRedirect_Do(t *testing.T) {
var ts2URL string
ts1 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
want := http.Header{
"Referer": []string{ts2URL},
"Accept-Encoding": []string{"gzip"},
"Authorization": []string{"hunter2"},
}
for k, v := range want {
if !reflect.DeepEqual(r.Header[k], v) {
t.Errorf("Request.Header = %#v; want %#v", r.Header[k], v)
}
}
if t.Failed() {
w.Header().Set("Result", "got errors")
} else {
w.Header().Set("Result", "ok")
}
}))
defer ts1.Close()
ts2 := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, ts1.URL, http.StatusFound)
}))
defer ts2.Close()
ts2URL = ts2.URL
tr := &http.Transport{}
defer tr.CloseIdleConnections()
d := &defaultClient{}
c := &http.Client{
Transport: tr,
CheckRedirect: d.AuthedCheckRedirect,
}
req, _ := http.NewRequest("GET", ts2.URL, nil)
req.Header.Add("Cookie", "foo=bar")
req.Header.Add("Authorization", "hunter2")
req.Header.Add("Howdy", "doody")
req.Header.Set("User-Agent", "Darth Vader, an extraterrestrial from the Planet Vulcan")
res, err := c.Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
if res.StatusCode != 200 {
t.Fatal(res.Status)
}
if got := res.Header.Get("Result"); got != "ok" {
t.Errorf("result = %q; want ok", got)
}
}
func Test_defaultClient_Do(t *testing.T) {
type args struct {
path string
method string
authorizer influx.Authorizer
params map[string]string
body io.Reader
}
tests := []struct {
name string
args args
want string
wantErr bool
}{
{
name: "test authorizer",
args: args{
path: "/tictactoe",
method: "GET",
authorizer: &influx.BasicAuth{
Username: "Steven Falken",
Password: "JOSHUA",
},
},
want: "Basic U3RldmVuIEZhbGtlbjpKT1NIVUE=",
},
{
name: "test authorizer",
args: args{
path: "/tictactoe",
method: "GET",
authorizer: &influx.BearerJWT{
Username: "minifig",
SharedSecret: "legos",
Now: func() time.Time { return time.Time{} },
},
},
want: "Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOi02MjEzNTU5Njc0MCwidXNlcm5hbWUiOiJtaW5pZmlnIn0.uwFGBQ3MykqEmk9Zx0sBdJGefcESVEXG_qt0C1J8b_aS62EAES-Q1FwtURsbITNvSnfzMxYFnkbSG0AA1pEzWw",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/tictactoe" {
t.Fatal("Expected request to '/query' but was", r.URL.Path)
}
got, ok := r.Header["Authorization"]
if !ok {
t.Fatal("No Authorization header")
}
if got[0] != tt.want {
t.Fatalf("Expected auth %s got %s", tt.want, got)
}
rw.Write([]byte(`{}`))
}))
defer ts.Close()
d := &defaultClient{}
u, _ := url.Parse(ts.URL)
_, err := d.Do(u, tt.args.path, tt.args.method, tt.args.authorizer, tt.args.params, tt.args.body)
if (err != nil) != tt.wantErr {
t.Errorf("defaultClient.Do() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}