github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/config/config_test.go (about)

     1  package config_test
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"reflect"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/qri-io/qri/config"
    14  	testcfg "github.com/qri-io/qri/config/test"
    15  	"github.com/sergi/go-diff/diffmatchpatch"
    16  )
    17  
    18  func TestReadFromFile(t *testing.T) {
    19  	_, err := config.ReadFromFile("testdata/default.yaml")
    20  	if err != nil {
    21  		t.Errorf("error reading config: %s", err.Error())
    22  		return
    23  	}
    24  
    25  	_, err = config.ReadFromFile("foobar")
    26  	if err == nil {
    27  		t.Error("expected read from bad path to error")
    28  		return
    29  	}
    30  }
    31  
    32  func TestWriteToFile(t *testing.T) {
    33  	path := filepath.Join(os.TempDir(), "config.yaml")
    34  	t.Log(path)
    35  	cfg := testcfg.DefaultConfigForTesting()
    36  	if err := cfg.WriteToFile(path); err != nil {
    37  		t.Errorf("error writing config: %s", err.Error())
    38  		return
    39  	}
    40  
    41  	if err := cfg.WriteToFile("/not/a/path/foo"); err == nil {
    42  		t.Error("expected write bad path to error")
    43  		return
    44  	}
    45  }
    46  
    47  func TestWriteToFileWithExtraData(t *testing.T) {
    48  	path := filepath.Join(os.TempDir(), "config.yaml")
    49  	t.Log(path)
    50  	cfg := config.Config{
    51  		Revision: config.CurrentConfigRevision,
    52  		Profile: &config.ProfilePod{
    53  			ID:       "QmU27VdAEUL5NGM6oB56htTxvHLfcGZgsgxrJTdVr2k4zs",
    54  			Peername: "test_peername",
    55  			Created:  time.Unix(1234567890, 0).In(time.UTC),
    56  			Updated:  time.Unix(1234567890, 0).In(time.UTC),
    57  		},
    58  	}
    59  	cfg.Profile.PeerIDs = []string{"/test_network/testPeerID"}
    60  	cfg.Profile.NetworkAddrs = []string{"foo", "bar", "baz"}
    61  
    62  	if err := cfg.WriteToFile(path); err != nil {
    63  		t.Errorf("error writing config: %s", err.Error())
    64  		return
    65  	}
    66  
    67  	golden := "testdata/simple.yaml"
    68  	f1, err := ioutil.ReadFile(golden)
    69  	if err != nil {
    70  		t.Errorf("error reading golden file: %s", err.Error())
    71  	}
    72  	f2, err := ioutil.ReadFile(path)
    73  	if err != nil {
    74  		t.Errorf("error reading written file: %s", err.Error())
    75  	}
    76  
    77  	dmp := diffmatchpatch.New()
    78  	diffs := dmp.DiffMain(string(f1), string(f2), false)
    79  	if len(diffs) > 1 {
    80  		fmt.Println(dmp.DiffPrettyText(diffs))
    81  		t.Errorf("failed to match: %s <> %s", golden, path)
    82  	}
    83  }
    84  
    85  func TestConfigSummaryString(t *testing.T) {
    86  	summary := testcfg.DefaultConfigForTesting().SummaryString()
    87  	t.Log(summary)
    88  	if !strings.Contains(summary, "API") {
    89  		t.Errorf("expected summary to list API port")
    90  	}
    91  }
    92  
    93  func TestConfigGet(t *testing.T) {
    94  	cfg := testcfg.DefaultConfigForTesting()
    95  	cases := []struct {
    96  		path   string
    97  		expect interface{}
    98  		err    string
    99  	}{
   100  		{"foo", nil, "at \"foo\": not found"},
   101  		{"p2p.enabled", true, ""},
   102  		{"p2p.QriBootstrapAddrs.foo", nil, "at \"p2p.QriBootstrapAddrs.foo\": need int, got string: \"foo\""},
   103  		{"p2p.QriBootstrapAddrs.0", cfg.P2P.QriBootstrapAddrs[0], ""},
   104  		{"logging.levels.qriapi", cfg.Logging.Levels["qriapi"], ""},
   105  		{"logging.levels.foo", nil, "at \"logging.levels.foo\": not found"},
   106  	}
   107  
   108  	for i, c := range cases {
   109  		got, err := cfg.Get(c.path)
   110  		if !(err == nil && c.err == "" || err != nil && err.Error() == c.err) {
   111  			t.Errorf("case %d error mismatch. expected: %s, got: %s", i, c.err, err)
   112  			continue
   113  		}
   114  
   115  		if !reflect.DeepEqual(c.expect, got) {
   116  			t.Errorf("case %d result mismatch. expected: %v, got: %v", i, c.expect, got)
   117  			continue
   118  		}
   119  	}
   120  }
   121  
   122  func TestConfigSet(t *testing.T) {
   123  	cases := []struct {
   124  		path  string
   125  		value interface{}
   126  		err   string
   127  	}{
   128  		{"foo", nil, "at \"foo\": not found"},
   129  		{"p2p.enabled", false, ""},
   130  		{"p2p.qribootstrapaddrs.0", "wahoo", ""},
   131  		{"p2p.qribootstrapaddrs.0", false, "at \"p2p.qribootstrapaddrs.0\": need string, got bool: false"},
   132  		{"logging.levels.qriapi", "debug", ""},
   133  	}
   134  
   135  	for i, c := range cases {
   136  		cfg := testcfg.DefaultConfigForTesting()
   137  
   138  		err := cfg.Set(c.path, c.value)
   139  		if err != nil {
   140  			if err.Error() != c.err {
   141  				t.Errorf("case %d error mismatch. expected: %s, got: %s", i, c.err, err)
   142  			}
   143  			continue
   144  		} else if c.err != "" {
   145  			t.Errorf("case %d error mismatch. expected: %s, got: %s", i, c.err, err)
   146  		}
   147  
   148  		got, err := cfg.Get(c.path)
   149  		if err != nil {
   150  			t.Errorf("error getting set path: %s", err.Error())
   151  			continue
   152  		}
   153  
   154  		if !reflect.DeepEqual(c.value, got) {
   155  			t.Errorf("case %d result mismatch. expected: %v, got: %v", i, c.value, got)
   156  			continue
   157  		}
   158  	}
   159  }
   160  
   161  func TestImmutablePaths(t *testing.T) {
   162  	dc := testcfg.DefaultConfigForTesting()
   163  	for path := range config.ImmutablePaths() {
   164  		if _, err := dc.Get(path); err != nil {
   165  			t.Errorf("path %s default configuration error: %s", path, err.Error())
   166  		}
   167  	}
   168  }
   169  
   170  func TestConfigValidate(t *testing.T) {
   171  	if err := testcfg.DefaultConfigForTesting().Validate(); err != nil {
   172  		t.Errorf("error validating config: %s", err)
   173  	}
   174  
   175  	//  cases that should fail:
   176  	p := testcfg.DefaultConfigForTesting()
   177  
   178  	// Profile:
   179  	p.Profile = nil
   180  	if err := p.Validate(); err == nil {
   181  		t.Error("When given no Profile, config.Validate did not catch the error.")
   182  	}
   183  	p.Profile = testcfg.DefaultProfileForTesting()
   184  	p.Profile.Type = "badType"
   185  	if err := p.Validate(); err == nil {
   186  		t.Error("When given bad input in Profile, config.Validate did not catch the error.")
   187  	}
   188  	// Repo:
   189  	r := testcfg.DefaultConfigForTesting()
   190  	r.Repo.Type = "badType"
   191  	if err := r.Validate(); err == nil {
   192  		t.Error("When given bad input in Repo, config.Validate did not catch the error.")
   193  	}
   194  
   195  	// Logging:
   196  	l := testcfg.DefaultConfigForTesting()
   197  	l.Logging.Levels["qriapi"] = "badType"
   198  	if err := l.Validate(); err == nil {
   199  		t.Error("When given bad input in Logging, config.Validate did not catch the error.")
   200  	}
   201  }
   202  
   203  func TestConfigCopy(t *testing.T) {
   204  	cases := []struct {
   205  		config *config.Config
   206  	}{
   207  		{testcfg.DefaultConfigForTesting()},
   208  	}
   209  	for i, c := range cases {
   210  		cpy := c.config.Copy()
   211  		if !reflect.DeepEqual(cpy, c.config) {
   212  			t.Errorf("Config Copy test case %v, config structs are not equal: \ncopy: %v, \noriginal: %v", i, cpy, c.config)
   213  			continue
   214  		}
   215  		cpy.API.AllowedOrigins[0] = ""
   216  		if reflect.DeepEqual(cpy, c.config) {
   217  			t.Errorf("Config Copy test case %v, editing one config struct should not affect the other: \ncopy: %v, \noriginal: %v", i, cpy, c.config)
   218  			continue
   219  		}
   220  	}
   221  }