github.com/sona-tar/ghs@v0.0.0-20170415134710-bed1b2953748/search_test.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"net/url"
     8  	"reflect"
     9  	"strings"
    10  	"testing"
    11  )
    12  
    13  type pageTestReulst struct {
    14  	printLastPage int
    15  	printMax      int
    16  }
    17  
    18  func TestSearch_Page(t *testing.T) {
    19  	assert := func(result interface{}, want interface{}) {
    20  		if !reflect.DeepEqual(result, want) {
    21  			t.Errorf("Returned %+v, want %+v", result, want)
    22  		}
    23  	}
    24  	// pageTest: max,      total, perPage
    25  	// Result:   lastPage, max
    26  	// normal test
    27  	assert(pageTest(1000, 1000, 100), &pageTestReulst{10, 1000})
    28  	// total test
    29  	assert(pageTest(1000, 100, 100), &pageTestReulst{1, 100})
    30  	assert(pageTest(1000, 101, 100), &pageTestReulst{2, 101})
    31  	assert(pageTest(1000, 500, 100), &pageTestReulst{5, 500})
    32  	assert(pageTest(1000, 1, 100), &pageTestReulst{1, 1})
    33  	assert(pageTest(2000, 1000, 100), &pageTestReulst{10, 1000})
    34  	// max test
    35  	assert(pageTest(100, 1000, 100), &pageTestReulst{1, 100})
    36  	assert(pageTest(101, 1000, 100), &pageTestReulst{2, 101})
    37  	assert(pageTest(500, 1000, 100), &pageTestReulst{5, 500})
    38  	assert(pageTest(1, 1000, 100), &pageTestReulst{1, 1})
    39  	assert(pageTest(2000, 1000, 100), &pageTestReulst{10, 1000})
    40  	// perPage test
    41  	assert(pageTest(1000, 1000, 1), &pageTestReulst{1000, 1000})
    42  	assert(pageTest(1000, 1000, 2), &pageTestReulst{500, 1000})
    43  	assert(pageTest(1000, 1000, 10), &pageTestReulst{100, 1000})
    44  	assert(pageTest(1000, 1000, 50), &pageTestReulst{20, 1000})
    45  	assert(pageTest(1000, 1000, 1000), &pageTestReulst{1, 1000})
    46  }
    47  
    48  func pageTest(max int, total int, perPage int) *pageTestReulst {
    49  	Setup()
    50  	defer Teardown()
    51  	c := context.Background()
    52  
    53  	// create input
    54  	lastPage := ((total - 1) / perPage) + 1
    55  	url, _ := url.Parse(server.URL)
    56  	repo = NewRepo(NewSearch(c, option(max, perPage, url, "")))
    57  
    58  	// create output
    59  	mux.HandleFunc("/search/repositories", func(w http.ResponseWriter, r *http.Request) {
    60  		w.Header().Add("Link", HeaderLink(perPage, lastPage))
    61  		fmt.Fprintf(w, `{"total_count": %d, "items": [{"id":1}]}`, total)
    62  	})
    63  
    64  	// test
    65  	_, printLastPage, printMax, _ := repo.search.First(c)
    66  
    67  	return &pageTestReulst{
    68  		printLastPage: printLastPage,
    69  		printMax:      printMax,
    70  	}
    71  }
    72  
    73  func HeaderLink(perPage int, lastPage int) string {
    74  	link := func(per int, page int, rel string) string {
    75  		url := "https://api.github.com/search/repositories"
    76  		query := fmt.Sprintf("?q=ghs&per_page=%d&page=%d", per, page)
    77  		link := "<" + url + query + ">"
    78  		return link + "; " + fmt.Sprintf(`rel="%s"`, rel)
    79  	}
    80  	next := link(perPage, 2, "next")
    81  	last := link(perPage, lastPage, "last")
    82  	return "Link: " + next + ", " + last
    83  
    84  }
    85  
    86  func option(max int, perPage int, url *url.URL, token string) *SearchOpt {
    87  	return &SearchOpt{
    88  		sort:    "best match",
    89  		order:   "desc",
    90  		query:   "ghs",
    91  		perPage: perPage,
    92  		max:     max,
    93  		baseURL: url,
    94  		token:   token,
    95  	}
    96  }
    97  
    98  type requestTestReulst struct {
    99  	repolen  int
   100  	printMax int
   101  }
   102  
   103  func TestSearch_Request(t *testing.T) {
   104  	assert := func(result interface{}, want interface{}) {
   105  		if !reflect.DeepEqual(result, want) {
   106  			t.Errorf("Returned %+v, want %+v", result, want)
   107  		}
   108  	}
   109  
   110  	var handler func(w http.ResponseWriter, r *http.Request)
   111  	// Normal response
   112  	handler = func(w http.ResponseWriter, r *http.Request) {
   113  		testMethod(t, r, "GET")
   114  		testFormValues(t, r, values{
   115  			"q":        "ghs",
   116  			"sort":     "best match",
   117  			"order":    "desc",
   118  			"page":     "1",
   119  			"per_page": "100",
   120  		})
   121  		var items []string
   122  		for i := 1; i < 100+1; i++ {
   123  			items = append(items, fmt.Sprintf(`{"id":%d}`, i))
   124  		}
   125  		fmt.Fprintf(w, `{"total_count": 102, "items": [%s]}`, strings.Join(items, ","))
   126  	}
   127  	ret, _ := firstRequestTest(t, handler)
   128  	assert(ret, &requestTestReulst{100, 102})
   129  
   130  	// Repository not found
   131  	handler = func(w http.ResponseWriter, r *http.Request) {
   132  		testMethod(t, r, "GET")
   133  		testFormValues(t, r, values{
   134  			"q":        "ghs",
   135  			"sort":     "best match",
   136  			"order":    "desc",
   137  			"page":     "1",
   138  			"per_page": "100",
   139  		})
   140  		fmt.Fprintf(w, `{"total_count": 0, "items": []}`)
   141  	}
   142  	ret, _ = firstRequestTest(t, handler)
   143  	assert(ret, &requestTestReulst{0, 0})
   144  
   145  	// Invalid response
   146  	handler = func(w http.ResponseWriter, r *http.Request) {
   147  		testMethod(t, r, "GET")
   148  		testFormValues(t, r, values{
   149  			"q":        "ghs",
   150  			"sort":     "best match",
   151  			"order":    "desc",
   152  			"page":     "1",
   153  			"per_page": "100",
   154  		})
   155  		w.Header().Set("Content-Type", "text/plain")
   156  		w.WriteHeader(http.StatusNotFound)
   157  	}
   158  	ret, err := firstRequestTest(t, handler)
   159  	assert(strings.Contains(err.Error(), "404"), true)
   160  	assert(ret, &requestTestReulst{0, 0})
   161  
   162  	// Normal response
   163  	handler = func(w http.ResponseWriter, r *http.Request) {
   164  		testMethod(t, r, "GET")
   165  		testFormValues(t, r, values{
   166  			"q":        "ghs",
   167  			"sort":     "best match",
   168  			"order":    "desc",
   169  			"page":     "2",
   170  			"per_page": "100",
   171  		})
   172  		fmt.Fprint(w, `{"total_count": 102, "items": [{"id":1},{"id":2}]}`)
   173  	}
   174  	repoNum, _ := secondRequestTest(t, handler)
   175  	assert(repoNum, 2)
   176  	// Invalid response
   177  	handler = func(w http.ResponseWriter, r *http.Request) {
   178  		testMethod(t, r, "GET")
   179  		testFormValues(t, r, values{
   180  			"q":        "ghs",
   181  			"sort":     "best match",
   182  			"order":    "desc",
   183  			"page":     "2",
   184  			"per_page": "100",
   185  		})
   186  		w.Header().Set("Content-Type", "text/plain")
   187  		w.WriteHeader(http.StatusNotFound)
   188  	}
   189  	repoNum, err = secondRequestTest(t, handler)
   190  	assert(strings.Contains(err.Error(), "404"), true)
   191  	assert(repoNum, 0)
   192  }
   193  
   194  func firstRequestTest(t *testing.T, handler func(http.ResponseWriter, *http.Request)) (*requestTestReulst, error) {
   195  	Setup()
   196  	defer Teardown()
   197  	c := context.Background()
   198  
   199  	// create input
   200  	max := 1000
   201  	perPage := 100
   202  	url, _ := url.Parse(server.URL)
   203  	repo = NewRepo(NewSearch(c, option(max, perPage, url, "")))
   204  
   205  	// create output
   206  	mux.HandleFunc("/search/repositories", handler)
   207  
   208  	// test
   209  	repos, _, printMax, err := repo.search.First(c)
   210  
   211  	return &requestTestReulst{
   212  		repolen:  len(repos),
   213  		printMax: printMax,
   214  	}, err
   215  }
   216  
   217  func secondRequestTest(t *testing.T, handler func(http.ResponseWriter, *http.Request)) (int, error) {
   218  	Setup()
   219  	defer Teardown()
   220  	c := context.Background()
   221  
   222  	// create input
   223  	max := 1000
   224  	perPage := 100
   225  	url, _ := url.Parse(server.URL)
   226  	repo = NewRepo(NewSearch(c, option(max, perPage, url, "abcdefg")))
   227  
   228  	// create output
   229  	mux.HandleFunc("/search/repositories", handler)
   230  
   231  	// test
   232  	repos, err := repo.search.Exec(c, 2)
   233  
   234  	return len(repos), err
   235  }