Beispiel #1
0
func TestQueryQuery(t *testing.T) {
	inventory := New()
	query := Query{
		RowKey:    "Row",
		ColumnKey: "Column",
	}
	gFont := inventory.Query(query)
	test.VerifyFatal(t, 1, 0, true, nil == gFont)

	wFont := &font.Font{
		Family: "Amaranth",
		Format: font.EOT,
		Path:   filepath.Join(amf, "amaranth-regular.eot"),
		Style:  "normal",
		Weight: 400,
	}
	inventory.Put("Amaranth", "woff400normal", wFont)
	query = Query{
		RowKey:    "Amaranth",
		ColumnKey: "woff400normal",
	}
	gFont = inventory.Query(query)
	test.VerifyFatal(t, 2, 0, false, nil == gFont)
	test.Verify(t, 3, 0, wFont.Family, gFont.Family)
	test.Verify(t, 4, 0, true, wFont.Format.Equal(gFont.Format))
	test.Verify(t, 5, 0, wFont.Style, gFont.Style)
	test.Verify(t, 6, 0, wFont.Weight, gFont.Weight)
	test.Verify(t, 7, 0, wFont.Path, gFont.Path)
}
Beispiel #2
0
func TestMakeGzipHandler(t *testing.T) {
	handler := MakeGzipHandler(helloHandler)
	server := httptest.NewServer(handler)
	defer server.Close()

	client := http.Client{}
	req, err := http.NewRequest("GET", server.URL, nil)
	test.VerifyFatal(t, 1, 0, true, nil == err)

	req.Header.Add("Accept-Encoding", "gzip")

	resp, err := client.Do(req)
	defer resp.Body.Close()
	test.VerifyFatal(t, 2, 0, true, nil == err)

	wContentEncoding := "gzip"
	gContentEncoding := resp.Header.Get("Content-Encoding")
	test.Verify(t, 3, 0, wContentEncoding, gContentEncoding)

	buf := new(bytes.Buffer)
	gzipWriter := gzip.NewWriter(buf)
	fmt.Fprint(gzipWriter, "Hej!")
	err = gzipWriter.Close()
	test.VerifyFatal(t, 4, 0, true, nil == err)
	wBody := buf.Bytes()
	gBody, err := ioutil.ReadAll(resp.Body)
	test.VerifyFatal(t, 5, 0, true, nil == err)
	test.Verify(t, 6, 0, true, bytes.Equal(wBody, gBody))
}
Beispiel #3
0
func TestFontContents(t *testing.T) {
	font := &Font{
		Family: "Amaranth",
		Format: WOFF,
		Path:   filepath.Join(amf, "amaranth-regular.woff"),
		Style:  "normal",
		Weight: 400,
	}
	gContents, err := font.Contents()
	test.VerifyFatal(t, 1, 0, true, nil == err)
	wContents, err := ioutil.ReadFile(font.Path)
	test.VerifyFatal(t, 2, 0, true, nil == err)
	test.Verify(t, 3, 0, 0, bytes.Compare(wContents, gContents))
}
Beispiel #4
0
func TestFontModTime(t *testing.T) {
	font := &Font{
		Family: "Amaranth",
		Format: WOFF,
		Path:   filepath.Join(amf, "amaranth-regular.woff"),
		Style:  "normal",
		Weight: 400,
	}
	gModTime, err := font.ModTime()
	test.VerifyFatal(t, 1, 0, true, nil == err)
	fi, err := os.Stat(font.Path)
	test.VerifyFatal(t, 2, 0, true, nil == err)
	wModTime := fi.ModTime()
	test.Verify(t, 3, 0, true, gModTime.Equal(wModTime))
}
Beispiel #5
0
func TestReadJson(t *testing.T) {
	type TestJson struct {
		Test string
	}

	testJson := &TestJson{}
	err := ReadJson(filepath.Join(td, "test.json"), testJson)
	test.VerifyFatal(t, 1, 0, true, nil == err)
	test.Verify(t, 2, 0, "json", testJson.Test)
}
Beispiel #6
0
func TestWhitelistRead(t *testing.T) {
	gWhitelist := New()
	err := gWhitelist.Read(filepath.Join(td, "whitelist.json"))
	test.VerifyFatal(t, 1, 0, true, nil == err)
	wWhitelist := Whitelist{
		Domains: []string{
			"http://one/",
			"http://two/",
			"http://three/",
		},
	}
	test.VerifyFatal(t, 2, 0, wWhitelist.Size(), gWhitelist.Size())

	for i, wdomain := range wWhitelist.Domains {
		j := i + 1
		gdomain := gWhitelist.Domains[i]
		test.Verify(t, 3, j, wdomain, gdomain)
	}
}
Beispiel #7
0
func TestInventoryBuild(t *testing.T) {
	inventory := New()
	err := inventory.Build(fl)
	test.VerifyFatal(t, 1, 0, true, nil == err)
	wSize := len(InventoryBuildTestCases)
	test.VerifyFatal(t, 2, 0, wSize, inventory.Len())

	for i, c := range InventoryBuildTestCases {
		j := i + 1
		wFont := c.Font
		gFont := inventory.Query(c.Query)
		test.VerifyFatal(t, 3, j, false, nil == gFont)
		test.Verify(t, 4, j, wFont.Family, gFont.Family)
		test.Verify(t, 5, j, true, wFont.Format.Equal(gFont.Format))
		test.Verify(t, 6, j, wFont.Style, gFont.Style)
		test.Verify(t, 7, j, wFont.Weight, gFont.Weight)
		test.Verify(t, 8, j, wFont.Path, gFont.Path)
	}
}
Beispiel #8
0
func TestFontFaceFromFont(t *testing.T) {
	ff := &FontFace{}
	f := font.Font{
		Family: "Amaranth",
		Format: font.WOFF,
		Path:   filepath.Join(amf, "amaranth-regular.woff"),
		Style:  "normal",
		Weight: 400,
	}
	err := ff.FromFont(f)
	test.VerifyFatal(t, 1, 0, true, nil == err)
	data, err := f.Contents()
	test.Verify(t, 2, 0, util.Base64(data), ff.Base64Data)
	test.Verify(t, 3, 0, f.Family, ff.Family)
	test.Verify(t, 4, 0, f.Format.String(), ff.Format)
	wMimeType := f.MimeType()
	test.VerifyFatal(t, 5, 0, false, "" == wMimeType)
	test.Verify(t, 6, 0, wMimeType, ff.MimeType)
	test.Verify(t, 7, 0, f.Style, ff.Style)
	test.Verify(t, 8, 0, f.Weight, ff.Weight)
}
Beispiel #9
0
func TestQueries(t *testing.T) {
	for i, c := range QueriesCases {
		j := i + 1

		gqueries := Queries(c.Family, c.Format)
		gqueriesSize := len(gqueries)
		wqueriesSize := len(c.Queries)
		test.VerifyFatal(t, 1, j, wqueriesSize, gqueriesSize)

		for k, wquery := range c.Queries {
			gquery := gqueries[k]
			test.Verify(t, 2, j, wquery.RowKey, gquery.RowKey)
			test.Verify(t, 3, j, gquery.ColumnKey, gquery.ColumnKey)
		}
	}
}
Beispiel #10
0
func TestMetadataFonts(t *testing.T) {
	metadata := &Metadata{
		Family: "Amaranth",
		Subfamilies: []Subfamily{
			// Subfamily 1
			Subfamily{
				Basename: "amaranth-regular",
				Formats:  []string{"eot", "woff"},
				Style:    "normal",
				Weight:   400,
			},
			// Subfamily 2
			Subfamily{
				Basename: "amaranth-italic",
				Formats:  []string{"eot", "woff"},
				Style:    "italic",
				Weight:   400,
			},
			// Subfamily 3
			Subfamily{
				Basename: "amaranth-bold",
				Formats:  []string{"eot", "woff"},
				Style:    "normal",
				Weight:   700,
			},
			// Subfamily 4
			Subfamily{
				Basename: "amaranth-bolditalic",
				Formats:  []string{"eot", "woff"},
				Style:    "italic",
				Weight:   700,
			},
		},
		path: filepath.Join(amf, "metadata.json"),
	}
	gFonts := metadata.Fonts()
	wFonts := []*Font{
		// Font 1
		&Font{
			Family: "Amaranth",
			Format: EOT,
			Path:   filepath.Join(amf, "amaranth-regular.eot"),
			Style:  "normal",
			Weight: 400,
		},
		// Font 2
		&Font{
			Family: "Amaranth",
			Format: WOFF,
			Path:   filepath.Join(amf, "amaranth-regular.woff"),
			Style:  "normal",
			Weight: 400,
		},
		// Font 3
		&Font{
			Family: "Amaranth",
			Format: EOT,
			Path:   filepath.Join(amf, "amaranth-italic.eot"),
			Style:  "italic",
			Weight: 400,
		},
		// Font 4
		&Font{
			Family: "Amaranth",
			Format: WOFF,
			Path:   filepath.Join(amf, "amaranth-italic.woff"),
			Style:  "italic",
			Weight: 400,
		},
		// Font 5
		&Font{
			Family: "Amaranth",
			Format: EOT,
			Path:   filepath.Join(amf, "amaranth-bold.eot"),
			Style:  "normal",
			Weight: 700,
		},
		// Font 6
		&Font{
			Family: "Amaranth",
			Format: WOFF,
			Path:   filepath.Join(amf, "amaranth-bold.woff"),
			Style:  "normal",
			Weight: 700,
		},
		// Font 7
		&Font{
			Family: "Amaranth",
			Format: EOT,
			Path:   filepath.Join(amf, "amaranth-bolditalic.eot"),
			Style:  "italic",
			Weight: 700,
		},
		// Font 8
		&Font{
			Family: "Amaranth",
			Format: WOFF,
			Path:   filepath.Join(amf, "amaranth-bolditalic.woff"),
			Style:  "italic",
			Weight: 700,
		},
	}
	test.VerifyFatal(t, 1, 0, len(wFonts), len(gFonts))
	for i, wFont := range wFonts {
		j := i + 1
		gFont := gFonts[i]
		test.Verify(t, 2, j, wFont.Family, gFont.Family)
		test.Verify(t, 3, j, true, wFont.Format.Equal(gFont.Format))
		test.Verify(t, 4, j, wFont.Path, gFont.Path)
		test.Verify(t, 5, j, wFont.Style, gFont.Style)
		test.Verify(t, 6, j, wFont.Weight, gFont.Weight)
	}
}
Beispiel #11
0
func TestMetadataRead(t *testing.T) {
	gMetadata := new(Metadata)
	err := gMetadata.Read(filepath.Join(amf, "metadata.json"))
	test.VerifyFatal(t, 1, 0, true, nil == err)
	wMetadata := &Metadata{
		Family: "Amaranth",
		Subfamilies: []Subfamily{
			// Subfamily 1
			Subfamily{
				Basename: "amaranth-regular",
				Formats:  []string{"eot", "woff"},
				Style:    "normal",
				Weight:   400,
			},
			// Subfamily 2
			Subfamily{
				Basename: "amaranth-italic",
				Formats:  []string{"eot", "woff"},
				Style:    "italic",
				Weight:   400,
			},
			// Subfamily 3
			Subfamily{
				Basename: "amaranth-bold",
				Formats:  []string{"eot", "woff"},
				Style:    "normal",
				Weight:   700,
			},
			// Subfamily 4
			Subfamily{
				Basename: "amaranth-bolditalic",
				Formats:  []string{"eot", "woff"},
				Style:    "italic",
				Weight:   700,
			},
		},
		path: filepath.Join(amf, "metadata.json"),
	}
	test.Verify(t, 2, 0, wMetadata.Family, gMetadata.Family)

	gSubfamilies := gMetadata.Subfamilies
	wSubfamilies := wMetadata.Subfamilies
	test.VerifyFatal(t, 3, 0, len(wSubfamilies), len(gSubfamilies))
	for i, wSubfamily := range wMetadata.Subfamilies {
		j := i + 1

		gSubfamily := gMetadata.Subfamilies[i]
		test.Verify(t, 4, j, wSubfamily.Basename, gSubfamily.Basename)

		gFormats := gSubfamily.Formats
		wFormats := wSubfamily.Formats
		test.VerifyFatal(t, 5, j, len(wFormats), len(gFormats))
		for k, wFormat := range wFormats {
			gFormat := gFormats[k]
			test.Verify(t, 6, j, wFormat, gFormat)
		}

		test.Verify(t, 7, j, wSubfamily.Style, gSubfamily.Style)
		test.Verify(t, 8, j, wSubfamily.Weight, gSubfamily.Weight)
	}

	test.Verify(t, 9, 0, wMetadata.path, gMetadata.path)
}
Beispiel #12
0
func TestCssHandler(t *testing.T) {
	type Request struct {
		Method string
		URL    string
	}

	// Build an inventory.
	// Used in cases 6-7.
	inv := inventory.New()
	err := inv.Build(fl)
	test.VerifyFatal(t, 1, 0, true, err == nil)

	// Build an "allow all" whitelist.
	// Use this whitelist to allow all
	// referrers to fetch the resource.
	// Used in cases 3-7.
	aawl := whitelist.New()
	aawl.Domains = append(aawl.Domains, "")

	// Parse templates.
	// Used in cases 7-9.
	eot := filepath.Join(tp, "eot.css.tmpl")
	woff := filepath.Join(tp, "woff.css.tmpl")
	tmpl, err := template.ParseFiles(eot, woff)
	test.VerifyFatal(t, 2, 0, true, err == nil)

	// Execute template containing Amaranth Regular.
	// Used in case 7.
	ar := &font.Font{
		Family: "Amaranth",
		Format: font.WOFF,
		Path:   filepath.Join(amf, "amaranth-regular.woff"),
		Style:  "normal",
		Weight: 400,
	}
	var tmplData []*FontFace
	data, err := ar.Contents()
	test.VerifyFatal(t, 3, 0, true, err == nil)
	mimeType := ar.MimeType()
	test.VerifyFatal(t, 4, 0, false, "" == mimeType)
	arff := &FontFace{
		Base64Data: util.Base64(data),
		Family:     ar.Family,
		Format:     ar.Format.String(),
		MimeType:   mimeType,
		Style:      ar.Style,
		Weight:     ar.Weight,
	}
	buf := new(bytes.Buffer)
	tmplName := ar.Format.String() + ".css.tmpl"
	tmplData = append(tmplData, arff)
	err = tmpl.ExecuteTemplate(buf, tmplName, tmplData)
	test.VerifyFatal(t, 5, 0, true, nil == err)
	arBody := buf.Bytes()

	// Generate the entity tag corresponding to Amaranth Regular.
	// Uncompressed response.
	// Used in case 7.
	hash := md5.New()
	modtime, err := ar.ModTime()
	test.VerifyFatal(t, 6, 0, true, nil == err)
	io.WriteString(hash, modtime.String())
	arEtag := fmt.Sprintf("%x", hash.Sum(nil))
	// Gzip compressed response.
	// Used in cases 8-9.
	arEtagGzip := arEtag + "+gzip"

	var cases = []struct {
		Body        []byte
		Context     HandlerContext
		Header      map[string]string
		IfNoneMatch string // If-None-Match client request header.
		Request     *Request
		StatusCode  int
	}{
		// Case 1
		{
			Header: map[string]string{
				"Content-Type": "text/plain; charset=utf-8",
			},
			Request: &Request{
				Method: "POST",
				URL:    "",
			},
			StatusCode: http.StatusNotImplemented,
		},
		// Case 2
		{
			Header: map[string]string{
				"Content-Type": "text/plain; charset=utf-8",
			},
			Request: &Request{
				Method: "GET",
				URL:    "",
			},
			StatusCode: http.StatusForbidden,
		},
		// Case 3
		{
			Context: HandlerContext{
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Content-Type": "text/plain; charset=utf-8",
			},
			Request: &Request{
				Method: "GET",
				URL:    "?family=",
			},
			StatusCode: http.StatusBadRequest,
		},
		// Case 4
		{
			Context: HandlerContext{
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Content-Type": "text/plain; charset=utf-8",
			},
			Request: &Request{
				Method: "GET",
				URL:    "?family=Amaranth&format=nonexistent",
			},
			StatusCode: http.StatusBadRequest,
		},
		// Case 5
		{
			Context: HandlerContext{
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Content-Type": "text/plain; charset=utf-8",
			},
			Request: &Request{
				Method: "GET",
				URL:    "?family=|Amaranth",
			},
			StatusCode: http.StatusBadRequest,
		},
		// Case 6
		{
			Context: HandlerContext{
				Flags: Flags{
					Etag: true,
				},
				Inventory: *inv,
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Content-Type": "text/plain; charset=utf-8",
				"Etag":         "",
			},
			Request: &Request{
				Method: "GET",
				URL:    "?family=Nonexistent",
			},
			StatusCode: http.StatusBadRequest,
		},
		// Case 7
		{
			Body: arBody,
			Context: HandlerContext{
				Flags: Flags{
					CcMaxAge: 2592000,
					Etag:     true,
				},
				Inventory: *inv,
				Templates: *tmpl,
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Cache-Control": "max-age=2592000",
				"Content-Type":  "text/css; charset=utf-8",
				"Etag":          arEtag,
			},
			Request: &Request{
				Method: "GET",
				URL:    "?family=Amaranth",
			},
			StatusCode: http.StatusOK,
		},
		// Case 8
		{
			Body: arBody,
			Context: HandlerContext{
				Flags: Flags{
					Etag: true,
					Gzip: true,
				},
				Inventory: *inv,
				Templates: *tmpl,
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Cache-Control": "max-age=0",
				"Content-Type":  "text/css; charset=utf-8",
				"Etag":          arEtagGzip,
			},
			Request: &Request{
				Method: "GET",
				URL:    "?family=Amaranth",
			},
			StatusCode: http.StatusOK,
		},
		// Case 9
		{
			Context: HandlerContext{
				Flags: Flags{
					Etag: true,
					Gzip: true,
				},
				Inventory: *inv,
				Templates: *tmpl,
				Whitelist: *aawl,
			},
			Header: map[string]string{
				"Cache-Control": "max-age=0",
				"Etag":          arEtagGzip,
			},
			IfNoneMatch: arEtagGzip,
			Request: &Request{
				Method: "GET",
				URL:    "?family=Amaranth",
			},
			StatusCode: http.StatusNotModified,
		},
	}

	for i, c := range cases {
		j := i + 1

		handler := MakeHandler(CssHandler, c.Context)
		server := httptest.NewServer(handler)
		defer server.Close()

		client := http.Client{}
		reqURL := server.URL + c.Request.URL
		req, err := http.NewRequest(c.Request.Method, reqURL, nil)
		test.VerifyFatal(t, 6, j, true, nil == err)

		if c.IfNoneMatch != "" {
			req.Header.Add("If-None-Match", c.IfNoneMatch)
		}

		resp, err := client.Do(req)
		defer resp.Body.Close()
		test.VerifyFatal(t, 7, j, true, nil == err)
		test.Verify(t, 8, j, c.StatusCode, resp.StatusCode)

		wContentType := c.Header["Content-Type"]
		gContentType := resp.Header.Get("Content-Type")
		test.Verify(t, 9, j, wContentType, gContentType)

		wCacheControl := c.Header["Cache-Control"]
		gCacheControl := resp.Header.Get("Cache-Control")
		test.Verify(t, 10, j, wCacheControl, gCacheControl)

		wEtag := c.Header["Etag"]
		gEtag := resp.Header.Get("Etag")
		test.Verify(t, 11, j, wEtag, gEtag)

		if (c.StatusCode == http.StatusOK) &&
			(resp.StatusCode == http.StatusOK) {
			gbody, err := ioutil.ReadAll(resp.Body)
			test.VerifyFatal(t, 13, j, true, nil == err)
			wbody := c.Body
			test.Verify(t, 14, j, true, bytes.Equal(wbody, gbody))
		}
	}
}
Beispiel #13
0
func TestMakeHandler(t *testing.T) {
	var cases = []struct {
		Context HandlerContext
		Header  map[string]string
	}{
		// Case 1
		{
			Context: HandlerContext{
				Flags: Flags{
					AcAllowOrigin: false,
					Gzip:          true,
					Version:       "test/0.1",
				},
			},
			Header: map[string]string{
				"Server": "test/0.1",
				"Vary":   "Accept-Encoding",
			},
		},
		// Case 2
		{
			Context: HandlerContext{
				Flags: Flags{
					AcAllowOrigin: true,
					Gzip:          false,
					Version:       "test/0.1",
				},
			},
			Header: map[string]string{
				"Access-Control-Allow-Origin": "*",
				"Server":                      "test/0.1",
			},
		},
		// Case 3
		{
			Context: HandlerContext{
				Flags: Flags{
					AcAllowOrigin: false,
					Gzip:          true,
					Version:       "",
				},
			},
			Header: map[string]string{
				"Vary": "Accept-Encoding",
			},
		},
		// Case 4
		{
			Context: HandlerContext{
				Flags: Flags{},
			},
			Header: map[string]string{},
		},
	}

	for i, c := range cases {
		j := i + 1

		handler := MakeHandler(emptyHandler, c.Context)
		server := httptest.NewServer(handler)
		defer server.Close()

		client := http.Client{}
		resp, err := client.Get(server.URL)
		defer resp.Body.Close()
		test.VerifyFatal(t, 1, j, true, nil == err)

		wHeader := c.Header
		gHeader := resp.Header
		test.Verify(t, 2, j, wHeader["Server"], gHeader.Get("Server"))
		test.Verify(t, 3, j, wHeader["Vary"], gHeader.Get("Vary"))
		wAcAllowOrigin := wHeader["Access-Control-Allow-Origin"]
		gAcAllowOrigin := gHeader.Get("Access-Control-Allow-Origin")
		test.Verify(t, 4, j, wAcAllowOrigin, gAcAllowOrigin)
	}
}