From 5feba7e3a9a16893177bae9041d7a4b6ff904e42 Mon Sep 17 00:00:00 2001 From: Adam Chalmers Date: Mon, 5 Aug 2019 17:40:22 -0500 Subject: [PATCH] TUN-2147: Implemented ScopeUnmarshaler --- tunnelrpc/pogs/unmarshal.go | 41 ++++++++++++++++++++++ tunnelrpc/pogs/unmarshal_test.go | 60 ++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 tunnelrpc/pogs/unmarshal.go create mode 100644 tunnelrpc/pogs/unmarshal_test.go diff --git a/tunnelrpc/pogs/unmarshal.go b/tunnelrpc/pogs/unmarshal.go new file mode 100644 index 00000000..ef40ff0a --- /dev/null +++ b/tunnelrpc/pogs/unmarshal.go @@ -0,0 +1,41 @@ +package pogs + +import ( + "encoding/json" + "fmt" + + "github.com/pkg/errors" +) + +// ScopeUnmarshaler can marshal a Scope pog from JSON. +type ScopeUnmarshaler struct { + Scope Scope +} + +// UnmarshalJSON takes in a JSON string, and attempts to marshal it into a Scope. +// If successful, the Scope member of this ScopeUnmarshaler is set and nil is returned. +// If unsuccessful, returns an error. +func (su *ScopeUnmarshaler) UnmarshalJSON(b []byte) error { + var scopeJSON map[string]interface{} + if err := json.Unmarshal(b, &scopeJSON); err != nil { + return errors.Wrapf(err, "cannot unmarshal %s into scopeJSON", string(b)) + } + + if group, ok := scopeJSON["group"]; ok { + if val, ok := group.(string); ok { + su.Scope = NewGroup(val) + return nil + } + return fmt.Errorf("JSON should have been a Scope, but the 'group' key contained %v", group) + } + + if systemName, ok := scopeJSON["system_name"]; ok { + if val, ok := systemName.(string); ok { + su.Scope = NewSystemName(val) + return nil + } + return fmt.Errorf("JSON should have been a Scope, but the 'system_name' key contained %v", systemName) + } + + return fmt.Errorf("JSON should have been an object with one root key, either 'system_name' or 'group'") +} diff --git a/tunnelrpc/pogs/unmarshal_test.go b/tunnelrpc/pogs/unmarshal_test.go new file mode 100644 index 00000000..16f83eac --- /dev/null +++ b/tunnelrpc/pogs/unmarshal_test.go @@ -0,0 +1,60 @@ +package pogs + +import "testing" + +func TestScopeUnmarshaler_UnmarshalJSON(t *testing.T) { + type fields struct { + Scope Scope + } + type args struct { + b []byte + } + tests := []struct { + name string + fields fields + args args + wantErr bool + wantScope Scope + }{ + { + name: "group_successful", + args: args{b: []byte(`{"group": "my-group"}`)}, + wantScope: NewGroup("my-group"), + }, + { + name: "system_name_successful", + args: args{b: []byte(`{"system_name": "my-computer"}`)}, + wantScope: NewSystemName("my-computer"), + }, + { + name: "not_a_scope", + args: args{b: []byte(`{"x": "y"}`)}, + wantErr: true, + }, + { + name: "malformed_group", + args: args{b: []byte(`{"group": ["a", "b"]}`)}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + su := &ScopeUnmarshaler{ + Scope: tt.fields.Scope, + } + err := su.UnmarshalJSON(tt.args.b) + if !tt.wantErr { + if err != nil { + t.Errorf("ScopeUnmarshaler.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr) + } + if !eqScope(tt.wantScope, su.Scope) { + t.Errorf("Wanted scope %v but got scope %v", tt.wantScope, su.Scope) + } + } + }) + } +} + +func eqScope(s1, s2 Scope) bool { + return s1.Value() == s2.Value() && s1.PostgresType() == s2.PostgresType() +}