1/*
2Copyright 2013 The Perkeep Authors
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
15*/
16
17package main
18
19import (
20	"net/http"
21	"net/http/httptest"
22	"net/url"
23	"os"
24	"path/filepath"
25	"strings"
26	"testing"
27)
28
29func TestRedirect(t *testing.T) {
30	tests := []struct {
31		in   string
32		want string
33	}{
34		{"/foo", ""},
35		{"/gw/502aff1fd522c454e39a3723b596aca43d206d4e", "https://github.com/perkeep/perkeep/commit/502aff1fd522c454e39a3723b596aca43d206d4e"},
36		{"/gw/502AFF", "https://github.com/perkeep/perkeep/commit/502AFF"},
37		{"/gw/server", "https://github.com/perkeep/perkeep/blob/master/server"}, // redirects to /tree/ on github's side, which is fine
38		{"/code/?p=camlistore.git;a=commit;h=b0d2a8f0e5f27bbfc025a96ec3c7896b42d198ed", "https://github.com/perkeep/perkeep/commit/b0d2a8f0e5f27bbfc025a96ec3c7896b42d198ed"},
39		{"/docs/schema/", "/doc/schema/"},
40
41		// strip directory index files
42		{"/doc/README.md", "/doc/"},
43		{"/doc/index.html", "/doc/"},
44
45		// strip common file extensions
46		{"/doc/overview.md", "/doc/overview"},
47		{"/doc/overview.html", "/doc/overview"},
48		{"/doc/overview.txt", ""},
49	}
50	for _, tt := range tests {
51		u, err := url.ParseRequestURI(tt.in)
52		if err != nil {
53			t.Fatal(err)
54		}
55		got := redirectPath(u)
56		if got != tt.want {
57			t.Errorf("redirectPath(%q) = %q; want %q", tt.in, got, tt.want)
58		}
59	}
60
61}
62
63func TestIsIssueRequest(t *testing.T) {
64	wantNum := "https://github.com/perkeep/perkeep/issues/34"
65	wantList := "https://github.com/perkeep/perkeep/issues"
66	tests := []struct {
67		urlPath   string
68		redirects bool
69		dest      string
70	}{
71		{"/issue", true, wantList},
72		{"/issue/", true, wantList},
73		{"/issue/34", true, wantNum},
74		{"/issue34", false, ""},
75		{"/issues", true, wantList},
76		{"/issues/", true, wantList},
77		{"/issues/34", true, wantNum},
78		{"/issues34", false, ""},
79		{"/bugs", true, wantList},
80		{"/bugs/", true, wantList},
81		{"/bugs/34", true, wantNum},
82		{"/bugs34", false, ""},
83	}
84	for _, tt := range tests {
85		dest, ok := issueRedirect(tt.urlPath)
86		if ok != tt.redirects || dest != tt.dest {
87			t.Errorf("issueRedirect(%q) = %q, %v; want %q, %v", tt.urlPath, dest, ok, tt.dest, tt.redirects)
88		}
89	}
90}
91
92func TestDocHandler(t *testing.T) {
93	// Set up environment
94	var err error
95	*root, err = os.Getwd()
96	if err != nil {
97		t.Fatalf("Failed to getwd: %v", err)
98	}
99	*root = filepath.Join(*root, "..")
100	readTemplates()
101
102	tests := []struct {
103		path       string
104		status     int
105		wantSubstr string
106	}{
107		// Test that the title tag is constructed from the h1 element
108		{"/website/testdata/sample", http.StatusOK,
109			"<title>Lorem Ipsum - Perkeep</title>"},
110		// Test that an html extension redirects to the base path
111		{"/website/testdata/sample.html", 302, "Found"},
112	}
113
114	for _, tt := range tests {
115		// Construct a request that maps to the given path
116		req, err := http.NewRequest("GET", tt.path, nil)
117		if err != nil {
118			t.Fatal(err)
119		}
120
121		rr := httptest.NewRecorder()
122		handler := http.HandlerFunc(docHandler)
123		handler.ServeHTTP(rr, req)
124
125		// Check the status code is what we expect.
126		if status := rr.Code; status != tt.status {
127			t.Errorf("for path %s, code=%v want %v", tt.path, status, tt.status)
128		}
129
130		// Check that the output contains the specified substring
131		if !strings.Contains(rr.Body.String(), tt.wantSubstr) {
132			t.Errorf("for path %s, got %q should contain %q",
133				tt.path, rr.Body.String(), tt.wantSubstr)
134		}
135	}
136}
137