Skip to content
Snippets Groups Projects
generate_basic_tests.go 10.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Copyright 2017 The go-netbox Authors.
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    
    //+build ignore
    
    package main
    
    import (
    	"bytes"
    	"flag"
    	"fmt"
    	"go/format"
    	"log"
    	"os"
    	"text/template"
    	"time"
    )
    
    func main() {
    	typeName := flag.String("type-name", "Example", "Name of the type to use (e.g. TenantGroup).")
    	serviceName := flag.String("service-name", "ExampleService", "Name of the service to create (e.g. TenantGroupsService).")
    	endpoint := flag.String("endpoint", "tenancy", "Name of the endpoint (e.g. dcim, ipam, tenancy).")
    	service := flag.String("service", "example", "Name of the service below endpoint (e.g. tenant-groups).")
    	clientEndpoint := flag.String("client-endpoint", "Tenancy", "Name of the client endpoint (e.g. DCIM, IPAM, Tenancy).")
    	clientService := flag.String("client-service", "TenantGroups", "Name of the client service (e.g. TenantGroups, Tenants).")
    	withoutListOpts := flag.Bool("without-list-opts", false, "Disable list options for this endpoint.")
    
    	flag.Parse()
    
    	b := &bytes.Buffer{}
    	functionsTemplate.Execute(b, struct {
    		Timestamp      time.Time
    		TypeName       string
    		ServiceName    string
    		Endpoint       string
    		Service        string
    		ClientEndpoint string
    		ClientService  string
    		ListOpts       bool
    		JSONTag        func(string) string
    	}{
    		Timestamp:      time.Now(),
    		TypeName:       *typeName,
    		ServiceName:    *serviceName,
    		Endpoint:       *endpoint,
    		Service:        *service,
    		ClientEndpoint: *clientEndpoint,
    		ClientService:  *clientService,
    		ListOpts:       !*withoutListOpts,
    		JSONTag:        func(name string) string { return "`json:\"" + name + "\"`" },
    	})
    
    	// go fmt
    	res, err := format.Source(b.Bytes())
    	if err != nil {
    		log.Fatal(err)
    	}
    
    	f, err := os.Create(fmt.Sprintf("%s_%s_basic_test.go", *endpoint, *service))
    	if err != nil {
    		log.Fatal(err)
    	}
    	defer f.Close()
    
    	_, err = f.Write(res)
    	if err != nil {
    		log.Fatal(err)
    	}
    
    }
    
    var functionsTemplate = template.Must(template.New("").Parse(`// Copyright 2017 The go-netbox Authors.
    //
    // Licensed under the Apache License, Version 2.0 (the "License");
    // you may not use this file except in compliance with the License.
    // You may obtain a copy of the License at
    //
    //   http://www.apache.org/licenses/LICENSE-2.0
    //
    // Unless required by applicable law or agreed to in writing, software
    // distributed under the License is distributed on an "AS IS" BASIS,
    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    // See the License for the specific language governing permissions and
    // limitations under the License.
    
    
    // Code generated by generate_basic_tests.go. DO NOT EDIT.
    
    
    package netbox
    
    import (
    	"encoding/json"
    	"errors"
    	"fmt"
    	"net/http"
    	"reflect"
    	"testing"
    )
    
    // Using this to override MarshalJSON
    // In all cases when posting data to netbox-API, the {{ .TypeName }}.MarshalJSON is what you want,
    // but not here as a return in testHandler
    type serverData{{ .TypeName }} {{ .TypeName }}
    
    func convertToServerData{{ .TypeName }}(data []*{{ .TypeName }}) []*serverData{{ .TypeName }} {
    	dataWant := make([]*serverData{{ .TypeName }}, len(data))
    	for i := range data {
    		tmp := serverData{{ .TypeName }}(*data[i])
    		dataWant[i] = &tmp
    	}
    	return dataWant
    }
    
    func TestBasic{{ .TypeName }}Get(t *testing.T) {
    	var tests = []struct {
    		desc      string
    		want      *{{ .TypeName }}
    	}{
    		{
    			desc:      "Simple {{ .TypeName }}",
    			want:      test{{ .TypeName }}(1),
    		},
    	}
    
    	for i, tt := range tests {
    		t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
    			serverData := serverData{{ .TypeName }}(*tt.want)
    
    			c, done := testClient(t, testHandler(t, http.MethodGet, "/api/{{ .Endpoint }}/{{ .Service }}/1/", &serverData))
    			defer done()
    
    			res, err := c.{{ .ClientEndpoint }}.{{ .ClientService }}.Get(1)
    			if err != nil {
    				t.Fatalf("unexpected error from Client.{{ .ClientEndpoint }}.{{ .ClientService }}.Get: %v", err)
    			}
    
    			if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
    				t.Fatalf("unexpected {{ .TypeName }}:\n- want: %v\n-  got: %v", want, got)
    			}
    		})
    	}
    }
    
    func TestBasic{{ .TypeName }}Get404(t *testing.T) {
    	c, done := testClient(t, testStatusHandler(t, http.MethodGet, "/api/{{ .Endpoint }}/{{ .Service }}/1/", &struct {
    		Detail string {{ call .JSONTag "detail" }}
    	}{
    		Detail: "Not found.",
    	},
    		http.StatusNotFound))
    	defer done()
    
    	res, err := c.{{ .ClientEndpoint }}.{{ .ClientService }}.Get(1)
    	errstr := "404 - Not found."
    	if want, got := errors.New(errstr), err; !reflect.DeepEqual(want, got) {
    		t.Fatalf("unexpected error from Client.{{ .ClientEndpoint }}.{{ .ClientService }}.Get:\n- want: %v\n-  got: %v", want, got)
    	}
    
    	if res != nil {
    		t.Fatalf("unexpected result:\n- want: %v\n-  got: %v", nil, res)
    	}
    }
    
    func TestBasicListExtract{{ .TypeName }}(t *testing.T) {
    	want := []*{{ .TypeName }}{
    		test{{ .TypeName }}(1),
    		test{{ .TypeName }}(2),
    	}
    	serverWant := convertToServerData{{ .TypeName }}(want)
    	serverData, _ := json.Marshal(serverWant)
    	c, done := testClient(t, testHandler(t, http.MethodGet, "/api/{{ .Endpoint }}/{{ .Service }}/", &pageData{
    		Count:       2,
    		NextURL:     "",
    		PreviousURL: "",
    		Results:     serverData,
    	}))
    	defer done()
    
    	{{ if .ListOpts -}}
    	page := c.{{ .ClientEndpoint }}.{{ .ClientService }}.List(nil)
    	{{ else }}
    	page := c.{{ .ClientEndpoint }}.{{ .ClientService }}.List()
    	{{ end }}
    	if page == nil {
    		t.Fatalf("unexpexted result from c.{{ .ClientEndpoint }}.{{ .ClientService }}.List.")
    	}
    
    	got := []*{{ .TypeName }}{}
    	counter := 0
    	for page.Next() {
    		var err error
    		got, err = c.{{ .ClientEndpoint }}.{{ .ClientService }}.Extract(page)
    		if err != nil {
    			t.Fatalf("unexpected error from c.{{ .ClientEndpoint }}.{{ .ClientService }}.Extract: %v", err)
    		}
    		counter = counter + 1
    		if counter > 2 { // Safe guard
    			break
    		}
    	}
    	if counter != 1 {
    		t.Fatalf("unexpected page count:\n- want: 1\n-  got: %d", counter)
    	}
    
    	if !reflect.DeepEqual(want, got) {
    		t.Fatalf("unexpected result:\n- want: %v\n-  got: %v", want, got)
    	}
    
    	if page.Err() != nil {
    		t.Fatalf("unexpected error from page:\n- want: %v\n-  got: %v", want, got)
    	}
    }
    
    func TestBasicCreate{{ .TypeName }}(t *testing.T) {
    	var tests = []struct {
    		desc       string
    		data       *{{ .TypeName }}
    
    		serverData interface{}
    		status     int
    		errstr     string
    	}{
    		{
    			desc:       "Create with ID 0",
    			data:       test{{ .TypeName }}Create(1),
    
    			status:     0,
    			errstr:     "",
    			serverData: test{{ .TypeName }}(1),
    		},
    		{
    			desc:   "Create duplicate",
    			data:   test{{ .TypeName }}Create(1),
    
    			status: http.StatusBadRequest,
    			errstr: "400 - {\"name\":[\"{{ .ServiceName }} with this name already exists.\"]}\n",
    			serverData: &struct {
    				Name []string {{ call .JSONTag "name" }}
    			}{
    				Name: []string{"{{ .ServiceName }} with this name already exists."},
    			},
    		},
    	}
    
    	for i, tt := range tests {
    		t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
    			c, done := testClient(t, testStatusHandler(t, http.MethodPost, "/api/{{ .Endpoint }}/{{ .Service }}/", tt.serverData, tt.status))
    			defer done()
    
    			var terr error
    			if tt.errstr != "" {
    				terr = errors.New(tt.errstr) // Using errstr and initialize real err here, to satisfy golint
    			}
    
    			res, err := c.{{ .ClientEndpoint }}.{{ .ClientService }}.Create(tt.data)
    			if want, got := terr, err; !reflect.DeepEqual(want, got) {
    				t.Fatalf("unexpected error:\n- want: %v\n-  got: %v", want, got)
    			}
    			if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
    				t.Fatalf("unexpected {{ .TypeName }}:\n- want: %v\n-  got: %v", want, got)
    			}
    		})
    	}
    }
    
    func TestBasicUpdate{{ .TypeName }}(t *testing.T) {
    	var tests = []struct {
    		desc       string
    		data       *{{ .TypeName }}
    
    		serverData interface{}
    		status     int
    		errstr     string
    	}{
    		{
    
    			desc:       "Update with ID 1",
    
    			data:       test{{ .TypeName }}(1),
    
    			serverData: test{{ .TypeName }}(1),
    			status:     0,
    			errstr:     "",
    		},
    		{
    			desc: "Update not found",
    			data: test{{ .TypeName }}(1),
    
    			serverData: &struct {
    				Detail string
    			}{
    				Detail: "Not found.",
    			},
    			status: http.StatusNotFound,
    			errstr: "404 - Not found.",
    		},
    		{
    
    			desc: "Update to duplicate",
    
    			data: test{{ .TypeName }}(1),
    
    			serverData: &struct {
    				Name []string {{ call .JSONTag "name" }}
    			}{
    				Name: []string{"{{ .ServiceName }} with this name already exists."},
    			},
    			status: http.StatusBadRequest,
    			errstr: "400 - {\"name\":[\"{{ .ServiceName }} with this name already exists.\"]}\n",
    		},
    	}
    
    	for i, tt := range tests {
    		t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
    			c, done := testClient(t, testStatusHandler(t, http.MethodPatch, "/api/{{ .Endpoint }}/{{ .Service }}/1/", tt.serverData, tt.status))
    			defer done()
    
    			var terr error
    			if tt.errstr != "" {
    				terr = errors.New(tt.errstr) // Using errstr and initialize real err here, to satisfy golint
    			}
    
    			res, err := c.{{ .ClientEndpoint }}.{{ .ClientService }}.Update(tt.data)
    			if want, got := terr, err; !reflect.DeepEqual(want, got) {
    				t.Fatalf("unexpected error:\n- want: %v\n-  got: %v", want, got)
    			}
    			if want, got := tt.want, res; !reflect.DeepEqual(want, got) {
    				t.Fatalf("unexpected {{ .TypeName }}:\n- want: %v\n-  got: %v", want, got)
    			}
    		})
    	}
    }
    
    func TestBasicDelete{{ .TypeName }}(t *testing.T) {
    	var tests = []struct {
    		desc       string
    		data       *{{ .TypeName }}
    		serverData interface{}
    		status     int
    		errstr     string
    	}{
    		{
    			desc:       "Delete ID 1",
    			data:       test{{ .TypeName }}(1),
    			serverData: test{{ .TypeName }}(1),
    			status:     0,
    			errstr:     "",
    		},
    		{
    			desc: "Delete not Found",
    			data: test{{ .TypeName }}(1),
    			serverData: &struct {
    				Detail string {{ call .JSONTag "detail" }}
    			}{
    				Detail: "Not found.",
    			},
    			status: http.StatusNotFound,
    			errstr: "404 - Not found.",
    		},
    	}
    
    	for i, tt := range tests {
    		t.Run(fmt.Sprintf("[%d] %s", i, tt.desc), func(t *testing.T) {
    			c, done := testClient(t, testStatusHandler(t, http.MethodDelete, "/api/{{ .Endpoint }}/{{ .Service }}/1/", tt.serverData, tt.status))
    			defer done()
    
    			var terr error
    			if tt.errstr != "" {
    				terr = errors.New(tt.errstr) // Using errstr and initialize real err here, to satisfy golint
    			}
    
    			err := c.{{ .ClientEndpoint }}.{{ .ClientService }}.Delete(tt.data)
    			if want, got := terr, err; !reflect.DeepEqual(want, got) {
    				t.Fatalf("unexpected error:\n- want: %v\n-  got: %v", want, got)
    			}
    		})
    	}
    }
    `))