diff --git a/pkg/settings/exporter_test.go b/pkg/settings/exporter_test.go index 2a9c1da29..6955564a5 100644 --- a/pkg/settings/exporter_test.go +++ b/pkg/settings/exporter_test.go @@ -4,61 +4,63 @@ import ( "testing" "github.com/jmoiron/sqlx/types" + "github.com/stretchr/testify/require" + "gopkg.in/yaml.v2" ) func TestExport(t *testing.T) { - ss := ValueSet{} - - ss = append(ss, ([]*Value{ - &Value{ - Name: "v_string", - Value: types.JSONText("\"string\""), + req := require.New(t) + tests := []struct { + name, rawValue string + parsedValue interface{} + }{ + { + name: "v_string", + rawValue: `"string"`, + parsedValue: yaml.MapItem{Key: "v_string", Value: "string"}, }, - &Value{ - Name: "v_float", - Value: types.JSONText("123"), + { + name: "v_int-as-float", + rawValue: "12.34", + parsedValue: yaml.MapItem{Key: "v_int-as-float", Value: 12.34}, }, - &Value{ - Name: "v_float", - Value: types.JSONText("12.34"), + { + name: "v_float", + rawValue: "123", + parsedValue: yaml.MapItem{Key: "v_float", Value: 123.0}, }, - &Value{ - Name: "v_bool", - Value: types.JSONText("true"), + { + name: "v_bool_true", + rawValue: "true", + parsedValue: yaml.MapItem{Key: "v_bool_true", Value: true}, }, - &Value{ - Name: "v_slice", - Value: types.JSONText("[1, \"string\", true]"), + { + name: "v_bool_false", + rawValue: "false", + parsedValue: yaml.MapItem{Key: "v_bool_false", Value: false}, }, - &Value{ - Name: "v_map", - Value: types.JSONText("{\"k1\": \"v1\",\"k2\": 2}"), + { + name: "v_slice", + rawValue: `[1, 1.23, "string", true, false]`, + parsedValue: yaml.MapItem{Key: "v_slice", Value: []interface{}{1.0, 1.23, "string", true, false}}, + }, + { + name: "v_map", + rawValue: `{"k1": "string","k2": 1,"k3":1.23,"k4":true,"k5":false}`, + parsedValue: yaml.MapItem{Key: "v_map", Value: map[string]interface{}{"k1": "string", "k2": 1.0, "k3": 1.23, "k4": true, "k5": false}}, }, - })...) - - tt := Export(ss) - - if _, ok := tt[0].Value.(string); !ok { - t.Errorf("Expecting %v to be string", tt[0].Value) } - if _, ok := tt[1].Value.(float64); !ok { - t.Errorf("Expecting %v to be float64", tt[1].Value) - } - - if _, ok := tt[2].Value.(float64); !ok { - t.Errorf("Expecting %v to be float64", tt[2].Value) - } - - if _, ok := tt[3].Value.(bool); !ok { - t.Errorf("Expecting %v to be bool", tt[3].Value) - } - - if _, ok := tt[4].Value.([]interface{}); !ok { - t.Errorf("Expecting %v to be []interface{}", tt[4].Value) - } - - if _, ok := tt[5].Value.(map[string]interface{}); !ok { - t.Errorf("Expecting %v to be map[string]interface {}", tt[5].Value) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + tt := Export(ValueSet{ + &Value{ + Name: test.name, + Value: types.JSONText(test.rawValue), + }, + }) + req.Len(tt, 1) + req.Equal(test.parsedValue, tt[0]) + }) } } diff --git a/pkg/settings/importer_test.go b/pkg/settings/importer_test.go index b5c9910fb..5d61b130c 100644 --- a/pkg/settings/importer_test.go +++ b/pkg/settings/importer_test.go @@ -10,11 +10,6 @@ import ( ) func TestSettingImport_CastSet(t *testing.T) { - type tv struct { - name string - value string - } - var aux interface{} req := require.New(t) f, err := os.Open("testdata/settings.yaml") @@ -26,39 +21,23 @@ func TestSettingImport_CastSet(t *testing.T) { imp := NewImporter() err = imp.CastSet(aux) req.Nil(err) - req.Len(imp.settings, 6) - tests := []tv{ - tv{ - name: "array", - value: "[\"v1\",\"v2\"]", - }, - tv{ - name: "object", - value: "{\"k1\":\"v1\",\"k2\":\"v2\"}", - }, - tv{ - name: "plain_b", - value: "true", - }, - tv{ - name: "plain_double", - value: "12.34", - }, - tv{ - name: "plain_double_2", - value: "12", - }, - tv{ - name: "plain_s", - value: "\"string\"", - }, + tests := map[string]string{ + "v_string": "\"string\"", + "v_float": "12.34", + "v_int-as-float": "123", + "v_bool_true": "true", + "v_bool_false": "false", + "v_slice": "[1,1.23,\"string\",true,false]", + "v_map": "{\"k1\":\"string\",\"k2\":1,\"k3\":1.23,\"k4\":true,\"k5\":false}", } - for _, t := range tests { - v := imp.settings.First(t.name) - vv, _ := types.JSONText(t.value).MarshalJSON() - ee, _ := v.Value.MarshalJSON() - req.Equal(vv, ee) + for k, test := range tests { + t.Run(k, func(t *testing.T) { + v := imp.settings.First(k) + vv, _ := types.JSONText(test).MarshalJSON() + ee, _ := v.Value.MarshalJSON() + req.Equal(ee, vv) + }) } } diff --git a/pkg/settings/testdata/settings.yaml b/pkg/settings/testdata/settings.yaml index a889e4e37..03778e70b 100644 --- a/pkg/settings/testdata/settings.yaml +++ b/pkg/settings/testdata/settings.yaml @@ -1,10 +1,17 @@ -array: -- v1 -- v2 -object: - k1: v1 - k2: v2 -plain_b: true -plain_double: 12.34 -plain_double_2: 12 -plain_s: string +v_string: string +v_float: 12.34 +v_int-as-float: 123 +v_bool_true: true +v_bool_false: false +v_slice: +- 1 +- 1.23 +- string +- true +- false +v_map: + k1: string + k2: 1 + k3: 1.23 + k4: true + k5: false diff --git a/tests/compose/settings_test.go b/tests/compose/settings_test.go new file mode 100644 index 000000000..cb8419802 --- /dev/null +++ b/tests/compose/settings_test.go @@ -0,0 +1,128 @@ +package compose + +import ( + "net/http" + "testing" + + "github.com/cortezaproject/corteza-server/compose/service" + tt "github.com/cortezaproject/corteza-server/compose/types" + "github.com/cortezaproject/corteza-server/pkg/settings" + "github.com/cortezaproject/corteza-server/tests/helpers" + "github.com/jmoiron/sqlx/types" + jsonpath "github.com/steinfletcher/apitest-jsonpath" +) + +func TestSettingsList(t *testing.T) { + h := newHelper(t) + h.allow(tt.ComposePermissionResource, "settings.read") + h.allow(tt.ComposePermissionResource, "settings.manage") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_cmp_k1.s1", Value: types.JSONText(`"t_cmp_v1"`)}, + &settings.Value{Name: "t_cmp_k1.s2", Value: types.JSONText(`"t_cmp_v2"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Get("/settings/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Present(`$.response[? @.name=="t_cmp_k1.s1"]`)). + Assert(jsonpath.Present(`$.response[? @.value=="t_cmp_v1"]`)). + Assert(jsonpath.Present(`$.response[? @.name=="t_cmp_k1.s2"]`)). + Assert(jsonpath.Present(`$.response[? @.value=="t_cmp_v2"]`)). + End() +} + +func TestSettingsList_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.ComposePermissionResource, "settings.read") + + h.apiInit(). + Get("/settings/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() +} + +func TestSettingsUpdate(t *testing.T) { + h := newHelper(t) + h.allow(tt.ComposePermissionResource, "settings.manage") + h.allow(tt.ComposePermissionResource, "settings.read") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_cmp_k1.s1", Value: types.JSONText(`"t_cmp_v1"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Patch("/settings/"). + JSON(`{"values":[{"name":"t_cmp_k1.s1","value":"t_cmp_v1_edited"},{"name":"t_cmp_k2.s1","value":"t_cmp_v2_new"}]}`). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + s, err := service.DefaultSettings.With(h.secCtx()).Get("t_cmp_k1.s1", 0) + h.a.NoError(err) + h.a.Equal(`"t_cmp_v1_edited"`, s.Value.String(), "existing key should be updated") + + s, err = service.DefaultSettings.With(h.secCtx()).Get("t_cmp_k2.s1", 0) + h.a.NoError(err) + h.a.Equal(`"t_cmp_v2_new"`, s.Value.String(), "new key should be added") +} + +func TestSettingsUpdate_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.ComposePermissionResource, "settings.manage") + + h.apiInit(). + Patch("/settings/"). + JSON(`{"values":[]}`). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to manage settings")). + End() +} + +func TestSettingsGet(t *testing.T) { + h := newHelper(t) + h.allow(tt.ComposePermissionResource, "settings.read") + h.allow(tt.ComposePermissionResource, "settings.manage") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_cmp_k1.s1", Value: types.JSONText(`"t_cmp_v1"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Get("/settings/t_cmp_k1.s1"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Present(`$.response.name=="t_cmp_k1.s1"`)). + Assert(jsonpath.Present(`$.response.value=="t_cmp_v1"`)). + End() + + h.apiInit(). + Get("/settings/t_cmp_k1.missing"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Equal(`$.response`, nil)). + End() +} + +func TestSettingsGet_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.ComposePermissionResource, "settings.read") + + h.apiInit(). + Get("/settings/t_cmp_k1.s1"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() +} diff --git a/tests/messaging/settings_test.go b/tests/messaging/settings_test.go new file mode 100644 index 000000000..536b0e17d --- /dev/null +++ b/tests/messaging/settings_test.go @@ -0,0 +1,128 @@ +package messaging + +import ( + "net/http" + "testing" + + "github.com/cortezaproject/corteza-server/messaging/service" + tt "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/settings" + "github.com/cortezaproject/corteza-server/tests/helpers" + "github.com/jmoiron/sqlx/types" + jsonpath "github.com/steinfletcher/apitest-jsonpath" +) + +func TestSettingsList(t *testing.T) { + h := newHelper(t) + h.allow(tt.MessagingPermissionResource, "settings.read") + h.allow(tt.MessagingPermissionResource, "settings.manage") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_msg_k1.s1", Value: types.JSONText(`"t_msg_v1"`)}, + &settings.Value{Name: "t_msg_k1.s2", Value: types.JSONText(`"t_msg_v2"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Get("/settings/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Present(`$.response[? @.name=="t_msg_k1.s1"]`)). + Assert(jsonpath.Present(`$.response[? @.value=="t_msg_v1"]`)). + Assert(jsonpath.Present(`$.response[? @.name=="t_msg_k1.s2"]`)). + Assert(jsonpath.Present(`$.response[? @.value=="t_msg_v2"]`)). + End() +} + +func TestSettingsList_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.MessagingPermissionResource, "settings.read") + + h.apiInit(). + Get("/settings/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() +} + +func TestSettingsUpdate(t *testing.T) { + h := newHelper(t) + h.allow(tt.MessagingPermissionResource, "settings.manage") + h.allow(tt.MessagingPermissionResource, "settings.read") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_msg_k1.s1", Value: types.JSONText(`"t_msg_v1"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Patch("/settings/"). + JSON(`{"values":[{"name":"t_msg_k1.s1","value":"t_msg_v1_edited"},{"name":"t_msg_k2.s1","value":"t_msg_v2_new"}]}`). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + s, err := service.DefaultSettings.With(h.secCtx()).Get("t_msg_k1.s1", 0) + h.a.NoError(err) + h.a.Equal(`"t_msg_v1_edited"`, s.Value.String(), "existing key should be updated") + + s, err = service.DefaultSettings.With(h.secCtx()).Get("t_msg_k2.s1", 0) + h.a.NoError(err) + h.a.Equal(`"t_msg_v2_new"`, s.Value.String(), "new key should be added") +} + +func TestSettingsUpdate_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.MessagingPermissionResource, "settings.manage") + + h.apiInit(). + Patch("/settings/"). + JSON(`{"values":[]}`). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to manage settings")). + End() +} + +func TestSettingsGet(t *testing.T) { + h := newHelper(t) + h.allow(tt.MessagingPermissionResource, "settings.read") + h.allow(tt.MessagingPermissionResource, "settings.manage") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_msg_k1.s1", Value: types.JSONText(`"t_msg_v1"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Get("/settings/t_msg_k1.s1"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Present(`$.response.name=="t_msg_k1.s1"`)). + Assert(jsonpath.Present(`$.response.value=="t_msg_v1"`)). + End() + + h.apiInit(). + Get("/settings/t_msg_k1.missing"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Equal(`$.response`, nil)). + End() +} + +func TestSettingsGet_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.MessagingPermissionResource, "settings.read") + + h.apiInit(). + Get("/settings/t_msg_k1.s1"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() +} diff --git a/tests/system/settings_test.go b/tests/system/settings_test.go index 70decbbf9..19dc97ad2 100644 --- a/tests/system/settings_test.go +++ b/tests/system/settings_test.go @@ -1,9 +1,128 @@ package system import ( + "net/http" "testing" + + "github.com/cortezaproject/corteza-server/pkg/settings" + "github.com/cortezaproject/corteza-server/system/service" + tt "github.com/cortezaproject/corteza-server/system/types" + "github.com/cortezaproject/corteza-server/tests/helpers" + "github.com/jmoiron/sqlx/types" + jsonpath "github.com/steinfletcher/apitest-jsonpath" ) -func TestSettings(t *testing.T) { - t.Skip("pending implementation") +func TestSettingsList(t *testing.T) { + h := newHelper(t) + h.allow(tt.SystemPermissionResource, "settings.read") + h.allow(tt.SystemPermissionResource, "settings.manage") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_sys_k1.s1", Value: types.JSONText(`"t_sys_v1"`)}, + &settings.Value{Name: "t_sys_k1.s2", Value: types.JSONText(`"t_sys_v2"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Get("/settings/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Present(`$.response[? @.name=="t_sys_k1.s1"]`)). + Assert(jsonpath.Present(`$.response[? @.value=="t_sys_v1"]`)). + Assert(jsonpath.Present(`$.response[? @.name=="t_sys_k1.s2"]`)). + Assert(jsonpath.Present(`$.response[? @.value=="t_sys_v2"]`)). + End() +} + +func TestSettingsList_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.SystemPermissionResource, "settings.read") + + h.apiInit(). + Get("/settings/"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() +} + +func TestSettingsUpdate(t *testing.T) { + h := newHelper(t) + h.allow(tt.SystemPermissionResource, "settings.manage") + h.allow(tt.SystemPermissionResource, "settings.read") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_sys_k1.s1", Value: types.JSONText(`"t_sys_v1"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Patch("/settings/"). + JSON(`{"values":[{"name":"t_sys_k1.s1","value":"t_sys_v1_edited"},{"name":"t_sys_k2.s1","value":"t_sys_v2_new"}]}`). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + End() + + s, err := service.DefaultSettings.With(h.secCtx()).Get("t_sys_k1.s1", 0) + h.a.NoError(err) + h.a.Equal(`"t_sys_v1_edited"`, s.Value.String(), "existing key should be updated") + + s, err = service.DefaultSettings.With(h.secCtx()).Get("t_sys_k2.s1", 0) + h.a.NoError(err) + h.a.Equal(`"t_sys_v2_new"`, s.Value.String(), "new key should be added") +} + +func TestSettingsUpdate_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.SystemPermissionResource, "settings.manage") + + h.apiInit(). + Patch("/settings/"). + JSON(`{"values":[]}`). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to manage settings")). + End() +} + +func TestSettingsGet(t *testing.T) { + h := newHelper(t) + h.allow(tt.SystemPermissionResource, "settings.read") + h.allow(tt.SystemPermissionResource, "settings.manage") + + err := service.DefaultSettings.With(h.secCtx()).BulkSet(settings.ValueSet{ + &settings.Value{Name: "t_sys_k1.s1", Value: types.JSONText(`"t_sys_v1"`)}, + }) + h.a.NoError(err) + + h.apiInit(). + Get("/settings/t_sys_k1.s1"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Present(`$.response.name=="t_sys_k1.s1"`)). + Assert(jsonpath.Present(`$.response.value=="t_sys_v1"`)). + End() + + h.apiInit(). + Get("/settings/t_sys_k1.missing"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertNoErrors). + Assert(jsonpath.Equal(`$.response`, nil)). + End() +} + +func TestSettingsGet_noPermissions(t *testing.T) { + h := newHelper(t) + h.deny(tt.SystemPermissionResource, "settings.read") + + h.apiInit(). + Get("/settings/t_sys_k1.s1"). + Expect(t). + Status(http.StatusOK). + Assert(helpers.AssertError("not allowed to read settings")). + End() }