influxdb/server/org_config_test.go

611 lines
15 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package server
import (
"bytes"
"encoding/json"
"io/ioutil"
"net/http/httptest"
"testing"
"github.com/influxdata/chronograf"
"github.com/influxdata/chronograf/log"
"github.com/influxdata/chronograf/mocks"
)
func TestOrganizationConfig(t *testing.T) {
type fields struct {
OrganizationConfigStore chronograf.OrganizationConfigStore
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
wants wants
}{
{
name: "Get organization configuration settings",
fields: fields{
OrganizationConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewer{
Columns: []chronograf.LogViewerColumn{
{
Name: "time",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
{
Name: "severity",
Position: 1,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
{
Type: "label",
Value: "icon",
},
{
Type: "label",
Value: "text",
},
},
},
{
Name: "timestamp",
Position: 2,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
},
},
{
Name: "message",
Position: 3,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
},
},
{
Name: "facility",
Position: 4,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
},
},
{
Name: "procid",
Position: 5,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
{
Type: "displayName",
Value: "Proc ID",
},
},
},
{
Name: "appname",
Position: 6,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
{
Type: "displayName",
Value: "Application",
},
},
},
{
Name: "host",
Position: 7,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "visible",
},
},
},
},
},
},
},
},
wants: wants{
statusCode: 200,
contentType: "application/json",
body: `{"links":{"self":"/chronograf/v1/config"},"auth":{"superAdminNewUsers":false}}`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
Store: &mocks.Store{
OrganizationConfigStore: tt.fields.OrganizationConfigStore,
},
Logger: log.New(log.DebugLevel),
}
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "http://any.url", nil)
s.Config(w, r)
resp := w.Result()
content := resp.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != tt.wants.statusCode {
t.Errorf("%q. Config() = %v, want %v", tt.name, resp.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. Config() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("%q. Config() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
}
})
}
}
func TestLogViewerOrganizationConfig(t *testing.T) {
type fields struct {
OrganizationConfigStore chronograf.OrganizationConfigStore
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
wants wants
}{
{
name: "Get log viewer configuration",
fields: fields{
OrganizationConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "severity",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "color",
Value: "emergency",
Name: "ruby",
},
{
Type: "color",
Value: "info",
Name: "rainforest",
},
{
Type: "displayName",
Value: "Log Severity",
},
},
},
},
},
},
},
},
wants: wants{
statusCode: 200,
contentType: "application/json",
body: `{"links":{"self":"/chronograf/v1/config/logviewer"},"columns":[{"name":"severity","position":0,"encodings":[{"type":"color","value":"emergency","name":"ruby"},{"type":"color","value":"info","name":"rainforest"},{"type":"displayName","value":"Log Severity"}]}]}`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
Store: &mocks.Store{
ConfigStore: tt.fields.ConfigStore,
},
Logger: log.New(log.DebugLevel),
}
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "http://any.url", nil)
s.LogViewerOrganizationConfig(w, r)
resp := w.Result()
content := resp.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != tt.wants.statusCode {
t.Errorf("%q. Config() = %v, want %v", tt.name, resp.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. Config() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("%q. Config() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
}
})
}
}
func TestReplaceLogViewerOrganizationConfig(t *testing.T) {
type fields struct {
ConfigStore chronograf.OrganizationConfigStore
}
type args struct {
payload interface{} // expects JSON serializable struct
}
type wants struct {
statusCode int
contentType string
body string
}
tests := []struct {
name string
fields fields
args args
wants wants
}{
{
name: "Set log viewer configuration",
fields: fields{
ConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "severity",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "color",
Value: "info",
Name: "rainforest",
},
{
Type: "visibility",
Value: "visible",
},
{
Type: "label",
Value: "icon",
},
},
},
},
},
},
},
},
args: args{
payload: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "severity",
Position: 1,
Encodings: []chronograf.ColumnEncoding{
{
Type: "color",
Value: "info",
Name: "pineapple",
},
{
Type: "color",
Value: "emergency",
Name: "ruby",
},
{
Type: "visibility",
Value: "visible",
},
{
Type: "label",
Value: "icon",
},
},
},
{
Name: "messages",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "displayName",
Value: "Log Messages",
},
{
Type: "visibility",
Value: "visible",
},
},
},
},
},
},
wants: wants{
statusCode: 200,
contentType: "application/json",
body: `{"links":{"self":"/chronograf/v1/config/logviewer"},"columns":[{"name":"severity","position":1,"encodings":[{"type":"color","value":"info","name":"pineapple"},{"type":"color","value":"emergency","name":"ruby"},{"type":"visibility","value":"visible"},{"type":"label","value":"icon"}]},{"name":"messages","position":0,"encodings":[{"type":"displayName","value":"Log Messages"},{"type":"visibility","value":"visible"}]}]}`,
},
},
{
name: "Set invalid log viewer configuration empty",
fields: fields{
ConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "severity",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "color",
Value: "info",
Name: "rainforest",
},
{
Type: "label",
Value: "icon",
},
{
Type: "visibility",
Value: "visible",
},
},
},
},
},
},
},
},
args: args{
payload: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{},
},
},
wants: wants{
statusCode: 400,
contentType: "application/json",
body: `{"code":400,"message":"Invalid log viewer config: must have at least 1 column"}`,
},
},
{
name: "Set invalid log viewer configuration - duplicate column name",
fields: fields{
ConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "procid",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
},
},
},
},
},
args: args{
payload: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "procid",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
{
Name: "procid",
Position: 1,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
},
},
},
wants: wants{
statusCode: 400,
contentType: "application/json",
body: `{"code":400,"message":"Invalid log viewer config: Duplicate column name procid"}`,
},
},
{
name: "Set invalid log viewer configuration - multiple columns with same position value",
fields: fields{
ConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "procid",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
},
},
},
},
},
args: args{
payload: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "procid",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
{
Name: "timestamp",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "visibility",
Value: "hidden",
},
},
},
},
},
},
wants: wants{
statusCode: 400,
contentType: "application/json",
body: `{"code":400,"message":"Invalid log viewer config: Multiple columns with same position value"}`,
},
},
{
name: "Set invalid log viewer configuration no visibility",
fields: fields{
ConfigStore: &mocks.OrganizationConfigStore{
OrganizationConfig: &chronograf.OrganizationConfig{
LogViewer: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "severity",
Position: 0,
Encodings: []chronograf.ColumnEncoding{
{
Type: "color",
Value: "info",
Name: "rainforest",
},
{
Type: "label",
Value: "icon",
},
},
},
},
},
},
},
},
args: args{
payload: chronograf.LogViewerConfig{
Columns: []chronograf.LogViewerColumn{
{
Name: "severity",
Position: 1,
Encodings: []chronograf.ColumnEncoding{
{
Type: "color",
Value: "info",
Name: "pineapple",
},
{
Type: "color",
Value: "emergency",
Name: "ruby",
},
{
Type: "label",
Value: "icon",
},
},
},
},
},
},
wants: wants{
statusCode: 400,
contentType: "application/json",
body: `{"code":400,"message":"Invalid log viewer config: missing visibility encoding in column severity"}`,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Service{
Store: &mocks.Store{
OrganizationConfigStore: tt.fields.OrganizationConfigStore,
},
Logger: log.New(log.DebugLevel),
}
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "http://any.url", nil)
buf, _ := json.Marshal(tt.args.payload)
r.Body = ioutil.NopCloser(bytes.NewReader(buf))
s.ReplaceLogViewerOrganizationConfig(w, r)
resp := w.Result()
content := resp.Header.Get("Content-Type")
body, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != tt.wants.statusCode {
t.Errorf("%q. Config() = %v, want %v", tt.name, resp.StatusCode, tt.wants.statusCode)
}
if tt.wants.contentType != "" && content != tt.wants.contentType {
t.Errorf("%q. Config() = %v, want %v", tt.name, content, tt.wants.contentType)
}
if eq, _ := jsonEqual(string(body), tt.wants.body); tt.wants.body != "" && !eq {
t.Errorf("%q. Config() = \n***%v***\n,\nwant\n***%v***", tt.name, string(body), tt.wants.body)
}
})
}
}