github.com/StackExchange/dnscontrol/v4@v4.11.0/pkg/js/js_test.go (about) 1 package js 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "os" 8 "path/filepath" 9 "testing" 10 "unicode" 11 12 "github.com/StackExchange/dnscontrol/v4/pkg/normalize" 13 "github.com/StackExchange/dnscontrol/v4/pkg/prettyzone" 14 "github.com/StackExchange/dnscontrol/v4/providers" 15 _ "github.com/StackExchange/dnscontrol/v4/providers/_all" 16 testifyrequire "github.com/stretchr/testify/require" 17 ) 18 19 const ( 20 testDir = "pkg/js/parse_tests" 21 errorDir = "pkg/js/error_tests" 22 ) 23 24 func init() { 25 os.Chdir("../..") // go up a directory so we helpers.js is in a consistent place. 26 } 27 28 func TestParsedFiles(t *testing.T) { 29 files, err := os.ReadDir(testDir) 30 if err != nil { 31 t.Fatal(err) 32 } 33 for _, f := range files { 34 name := f.Name() 35 36 // run all js files that start with a number. Skip others. 37 if filepath.Ext(name) != ".js" || !unicode.IsNumber(rune(name[0])) { 38 continue 39 } 40 t.Run(name, func(t *testing.T) { 41 var err error 42 43 // Compile the .js file: 44 conf, err := ExecuteJavaScript(string(filepath.Join(testDir, name)), true, nil) 45 if err != nil { 46 t.Fatal(err) 47 } 48 // for _, dc := range conf.Domains { 49 // normalize.UpdateNameSplitHorizon(dc) 50 // } 51 52 // Initialize any DNS providers mentioned. 53 for _, dProv := range conf.DNSProviders { 54 var pcfg = map[string]string{} 55 56 if dProv.Type == "-" { 57 // Pretend any "look up provider type in creds.json" results 58 // in a provider type that actually exists. 59 dProv.Type = "CLOUDFLAREAPI" 60 } 61 62 // Fake out any provider's validation tests. 63 switch dProv.Type { 64 case "CLOUDFLAREAPI": 65 pcfg["apitoken"] = "fake" 66 default: 67 } 68 _, err := providers.CreateDNSProvider(dProv.Type, pcfg, nil) 69 if err != nil { 70 t.Fatal(err) 71 } 72 } 73 74 // Test the JS compiled as expected (compare to the .json file) 75 actualJSON, err := json.MarshalIndent(conf, "", " ") 76 if err != nil { 77 t.Fatal(err) 78 } 79 testName := name[:len(name)-3] 80 expectedFile := filepath.Join(testDir, testName+".json") 81 expectedJSON, err := os.ReadFile(expectedFile) 82 if err != nil { 83 t.Fatal(err) 84 } 85 es := string(expectedJSON) 86 as := string(actualJSON) 87 _, _ = es, as 88 // When debugging, leave behind the actual result: 89 //os.WriteFile(expectedFile+".ACTUAL", []byte(as), 0644) 90 testifyrequire.JSONEqf(t, es, as, "EXPECTING %q = \n```\n%s\n```", expectedFile, as) 91 92 // For each domain, if there is a zone file, test against it: 93 94 errs := normalize.ValidateAndNormalizeConfig(conf) 95 if len(errs) != 0 { 96 t.Fatal(errs[0]) 97 } 98 99 var dCount int 100 for _, dc := range conf.Domains { 101 zoneFile := filepath.Join(testDir, testName, dc.Name+".zone") 102 expectedZone, err := os.ReadFile(zoneFile) 103 if err != nil { 104 continue 105 } 106 dCount++ 107 108 // Generate the zonefile 109 var buf bytes.Buffer 110 err = prettyzone.WriteZoneFileRC(&buf, dc.Records, dc.Name, 300, nil) 111 if err != nil { 112 t.Fatal(err) 113 } 114 actualZone := buf.String() 115 116 es := string(expectedZone) 117 as := actualZone 118 if es != as { 119 // On failure, leave behind the .ACTUAL file. 120 os.WriteFile(zoneFile+".ACTUAL", []byte(actualZone), 0644) 121 } 122 testifyrequire.Equal(t, es, as, "EXPECTING %q =\n```\n%s```", zoneFile, as) 123 } 124 if dCount > 0 && (len(conf.Domains) != dCount) { 125 t.Fatal(fmt.Errorf("only %d of %d domains in %q have zonefiles", dCount, len(conf.Domains), name)) 126 } 127 128 }) 129 130 } 131 } 132 133 func TestErrors(t *testing.T) { 134 tests := []struct{ desc, text string }{ 135 {"old dsp style", `D("foo.com","reg","dsp")`}, 136 {"MX no priority", `D("foo.com","reg",MX("@","test."))`}, 137 {"MX reversed", `D("foo.com","reg",MX("@","test.", 5))`}, 138 {"CF_REDIRECT With comma", `D("foo.com","reg",CF_REDIRECT("foo.com,","baaa"))`}, 139 {"CF_TEMP_REDIRECT With comma", `D("foo.com","reg",CF_TEMP_REDIRECT("foo.com","baa,a"))`}, 140 {"CF_WORKER_ROUTE With comma", `D("foo.com","reg",CF_WORKER_ROUTE("foo.com","baa,a"))`}, 141 {"Bad cidr", `D(reverse("foo.com"), "reg")`}, 142 {"Dup domains", `D("example.org", "reg"); D("example.org", "reg")`}, 143 {"Bad NAMESERVER", `D("example.com","reg", NAMESERVER("@","ns1.foo.com."))`}, 144 } 145 for _, tst := range tests { 146 t.Run(tst.desc, func(t *testing.T) { 147 if _, err := ExecuteJavaScript(tst.text, true, nil); err == nil { 148 t.Fatal("Expected error but found none") 149 } 150 }) 151 152 } 153 }