@ -4,8 +4,13 @@
package setting
import (
"cmp"
"encoding/json"
"testing"
"time"
jsonv2 "github.com/go-json-experiment/json"
"tailscale.com/util/syspolicy/internal"
)
func TestMergeSnapshots ( t * testing . T ) {
@ -432,3 +437,133 @@ Setting3 = user-decides`,
} )
}
}
func TestMarshalUnmarshalSnapshot ( t * testing . T ) {
tests := [ ] struct {
name string
snapshot * Snapshot
wantJSON string
wantBack * Snapshot
} {
{
name : "Nil" ,
snapshot : ( * Snapshot ) ( nil ) ,
wantJSON : "null" ,
wantBack : NewSnapshot ( nil ) ,
} ,
{
name : "Zero" ,
snapshot : & Snapshot { } ,
wantJSON : "{}" ,
} ,
{
name : "Bool/True" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "BoolPolicy" : RawItemOf ( true ) } ) ,
wantJSON : ` { "Settings": { "BoolPolicy": { "Value": true}}} ` ,
} ,
{
name : "Bool/False" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "BoolPolicy" : RawItemOf ( false ) } ) ,
wantJSON : ` { "Settings": { "BoolPolicy": { "Value": false}}} ` ,
} ,
{
name : "String/Non-Empty" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "StringPolicy" : RawItemOf ( "StringValue" ) } ) ,
wantJSON : ` { "Settings": { "StringPolicy": { "Value": "StringValue"}}} ` ,
} ,
{
name : "String/Empty" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "StringPolicy" : RawItemOf ( "" ) } ) ,
wantJSON : ` { "Settings": { "StringPolicy": { "Value": ""}}} ` ,
} ,
{
name : "Integer/NonZero" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "IntPolicy" : RawItemOf ( uint64 ( 42 ) ) } ) ,
wantJSON : ` { "Settings": { "IntPolicy": { "Value": 42}}} ` ,
} ,
{
name : "Integer/Zero" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "IntPolicy" : RawItemOf ( uint64 ( 0 ) ) } ) ,
wantJSON : ` { "Settings": { "IntPolicy": { "Value": 0}}} ` ,
} ,
{
name : "String-List" ,
snapshot : NewSnapshot ( map [ Key ] RawItem { "ListPolicy" : RawItemOf ( [ ] string { "Value1" , "Value2" } ) } ) ,
wantJSON : ` { "Settings": { "ListPolicy": { "Value": ["Value1", "Value2"]}}} ` ,
} ,
{
name : "Empty/With-Summary" ,
snapshot : NewSnapshot (
map [ Key ] RawItem { } ,
SummaryWith ( CurrentUserScope , NewNamedOrigin ( "TestSource" , DeviceScope ) ) ,
) ,
wantJSON : ` { "Summary": { "Origin": { "Name": "TestSource", "Scope": "Device"}, "Scope": "User"}} ` ,
} ,
{
name : "Setting/With-Summary" ,
snapshot : NewSnapshot (
map [ Key ] RawItem { "PolicySetting" : RawItemOf ( uint64 ( 42 ) ) } ,
SummaryWith ( CurrentUserScope , NewNamedOrigin ( "TestSource" , DeviceScope ) ) ,
) ,
wantJSON : ` {
"Summary" : { "Origin" : { "Name" : "TestSource" , "Scope" : "Device" } , "Scope" : "User" } ,
"Settings" : { "PolicySetting" : { "Value" : 42 } }
} ` ,
} ,
{
name : "Settings/With-Origins" ,
snapshot : NewSnapshot (
map [ Key ] RawItem {
"SettingA" : RawItemWith ( uint64 ( 42 ) , nil , NewNamedOrigin ( "SourceA" , DeviceScope ) ) ,
"SettingB" : RawItemWith ( "B" , nil , NewNamedOrigin ( "SourceB" , CurrentProfileScope ) ) ,
"SettingC" : RawItemWith ( true , nil , NewNamedOrigin ( "SourceC" , CurrentUserScope ) ) ,
} ,
) ,
wantJSON : ` {
"Settings" : {
"SettingA" : { "Value" : 42 , "Origin" : { "Name" : "SourceA" , "Scope" : "Device" } } ,
"SettingB" : { "Value" : "B" , "Origin" : { "Name" : "SourceB" , "Scope" : "Profile" } } ,
"SettingC" : { "Value" : true , "Origin" : { "Name" : "SourceC" , "Scope" : "User" } }
}
} ` ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
doTest := func ( t * testing . T , useJSONv2 bool ) {
var gotJSON [ ] byte
var err error
if useJSONv2 {
gotJSON , err = jsonv2 . Marshal ( tt . snapshot )
} else {
gotJSON , err = json . Marshal ( tt . snapshot )
}
if err != nil {
t . Fatal ( err )
}
if got , want , equal := internal . EqualJSONForTest ( t , gotJSON , [ ] byte ( tt . wantJSON ) ) ; ! equal {
t . Errorf ( "JSON: got %s; want %s" , got , want )
}
gotBack := & Snapshot { }
if useJSONv2 {
err = jsonv2 . Unmarshal ( gotJSON , & gotBack )
} else {
err = json . Unmarshal ( gotJSON , & gotBack )
}
if err != nil {
t . Fatal ( err )
}
if wantBack := cmp . Or ( tt . wantBack , tt . snapshot ) ; ! gotBack . Equal ( wantBack ) {
t . Errorf ( "Snapshot: got %+v; want %+v" , gotBack , wantBack )
}
}
t . Run ( "json" , func ( t * testing . T ) { doTest ( t , false ) } )
t . Run ( "jsonv2" , func ( t * testing . T ) { doTest ( t , true ) } )
} )
}
}