func TestRouterMultiRoute(t *testing.T) {
	e := New()
	r := e.router

	// Routes
	r.Add(GET, "/users", func(c *Context) error {
		c.Set("path", "/users")
		return nil
	}, e)
	r.Add(GET, "/users/:id", func(c *Context) error {
		return nil
	}, e)
	c := NewContext(nil, nil, e)

	// Route > /users
	h, _ := r.Find(GET, "/users", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, "/users", c.Get("path"))
	}

	// Route > /users/:id
	h, _ = r.Find(GET, "/users/1", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "1", c.P(0))
	}

	// Route > /user
	h, _ = r.Find(GET, "/user", c)
	assert.Nil(t, h)
}
func TestStoreGetCasts(t *testing.T) {
	casts := store.GetCasts()
	assert.NotNil(t, casts)
	assert.True(t, len(casts) > 0)
	assert.Equal(t, uint64(1), casts[0].ID)
	assert.Equal(t, "test.go", casts[0].URL)
}
func TestAddCast(t *testing.T) {
	r := createRouter()
	cast := &Cast{}

	// It should return an existing cast
	req := testRequest(r, "POST", "/library/casts", nil)
	req.Header.Set("Authorization", "token")
	req.PostForm = url.Values{}
	req.PostForm.Set("feedurl", "test.go")
	res := req.send()
	assert.Equal(t, 200, res.Code)
	json.Unmarshal(res.Body.Bytes(), cast)
	assert.Equal(t, "test.go", cast.URL)
	assert.Equal(t, "test", cast.Name)

	// There should still be only 2 subscriptions
	user := store.GetUser("test")
	assert.Len(t, user.Subscriptions, 2)

	// It should return 500 when the crawling fails
	req.PostForm.Set("feedurl", "dat_url")
	res = req.send()
	assert.Equal(t, 500, res.Code)

	// There should still be only 2 subscriptions
	user = store.GetUser("test")
	assert.Len(t, user.Subscriptions, 2)

	// It should return a new cast
	req.PostForm.Set("feedurl", testRSS)
	res = req.send()
	assert.Equal(t, 200, res.Code)
	json.Unmarshal(res.Body.Bytes(), cast)
	assert.Equal(t, testRSS, cast.URL)
	assert.Equal(t, "BSD Now HD", cast.Name)
	assert.NotNil(t, cast.Feed)

	// There should now be 3 subscriptions
	user = store.GetUser("test")
	assert.Len(t, user.Subscriptions, 3)

	// The new cast should be in the store
	cast = store.GetCastByURL(testRSS)
	assert.NotNil(t, cast)
	assert.Equal(t, "BSD Now HD", cast.Name)
	assert.NotNil(t, cast.Feed)
}
func TestRouterMatchAny(t *testing.T) {
	e := New()
	r := e.router
	r.Add(GET, "/users/*", func(*Context) error {
		return nil
	}, e)
	c := NewContext(nil, nil, e)

	h, _ := r.Find(GET, "/users/", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "", c.P(0))
	}

	h, _ = r.Find(GET, "/users/1", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "1", c.P(0))
	}
}
func TestRouterParamNames(t *testing.T) {
	e := New()
	r := e.router

	// Routes
	r.Add(GET, "/users", func(c *Context) error {
		c.Set("path", "/users")
		return nil
	}, e)
	r.Add(GET, "/users/:id", func(c *Context) error {
		return nil
	}, e)
	r.Add(GET, "/users/:uid/files/:fid", func(c *Context) error {
		return nil
	}, e)
	c := NewContext(nil, nil, e)

	// Route > /users
	h, _ := r.Find(GET, "/users", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, "/users", c.Get("path"))
	}

	// Route > /users/:id
	h, _ = r.Find(GET, "/users/1", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "id", c.pnames[0])
		assert.Equal(t, "1", c.P(0))
	}

	// Route > /users/:uid/files/:fid
	h, _ = r.Find(GET, "/users/1/files/1", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "uid", c.pnames[0])
		assert.Equal(t, "1", c.P(0))
		assert.Equal(t, "fid", c.pnames[1])
		assert.Equal(t, "1", c.P(1))
	}
}
func TestResponse(t *testing.T) {
	w := httptest.NewRecorder()
	r := NewResponse(w)

	// SetWriter
	r.SetWriter(w)

	// Writer
	assert.Equal(t, w, r.Writer())

	// Header
	assert.NotNil(t, r.Header())

	// WriteHeader
	r.WriteHeader(http.StatusOK)
	assert.Equal(t, http.StatusOK, r.status)

	// Committed
	assert.True(t, r.committed)

	// Already committed
	r.WriteHeader(http.StatusTeapot)
	assert.NotEqual(t, http.StatusTeapot, r.Status())

	// Status
	r.status = http.StatusOK
	assert.Equal(t, http.StatusOK, r.Status())

	// Write
	s := "echo"
	_, err := r.Write([]byte(s))
	assert.NoError(t, err)

	// Flush
	r.Flush()

	// Size
	assert.EqualValues(t, len(s), r.Size())

	// Hijack
	assert.Panics(t, func() {
		r.Hijack()
	})

	// CloseNotify
	assert.Panics(t, func() {
		r.CloseNotify()
	})

	// reset
	r.reset(httptest.NewRecorder())
}
func TestRouterMicroParam(t *testing.T) {
	e := New()
	r := e.router
	r.Add(GET, "/:a/:b/:c", func(c *Context) error {
		return nil
	}, e)
	c := NewContext(nil, nil, e)
	h, _ := r.Find(GET, "/1/2/3", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "1", c.P(0))
		assert.Equal(t, "2", c.P(1))
		assert.Equal(t, "3", c.P(2))
	}
}
func TestAddUser(t *testing.T) {
	err := store.AddUser(&User{
		Username: "******",
		Password: "******",
	})
	assert.Nil(t, err)

	user := store.GetUser("added")
	assert.NotNil(t, user)
	assert.Equal(t, "added", user.Username)
	assert.NotEmpty(t, user.Password)

	err = store.AddUser(&User{Username: "******"})
	assert.Equal(t, ErrUsernameUnavailable, err)
}
func TestRouterStatic(t *testing.T) {
	e := New()
	r := e.router
	path := "/folders/a/files/echo.gif"
	r.Add(GET, path, func(c *Context) error {
		c.Set("path", path)
		return nil
	}, e)
	c := NewContext(nil, nil, e)
	h, _ := r.Find(GET, path, c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, path, c.Get("path"))
	}
}
func TestEcho(t *testing.T) {
	e := New()
	req, _ := http.NewRequest(GET, "/", nil)
	rec := httptest.NewRecorder()
	c := NewContext(req, NewResponse(rec), e)

	// Router
	assert.NotNil(t, e.Router())

	// Debug
	e.SetDebug(true)
	assert.True(t, e.Debug())

	// DefaultHTTPErrorHandler
	e.DefaultHTTPErrorHandler(errors.New("error"), c)
	assert.Equal(t, http.StatusInternalServerError, rec.Code)
}
func TestRouterTwoParam(t *testing.T) {
	e := New()
	r := e.router
	r.Add(GET, "/users/:uid/files/:fid", func(*Context) error {
		return nil
	}, e)
	c := NewContext(nil, nil, e)

	h, _ := r.Find(GET, "/users/1/files/1", c)
	if assert.NotNil(t, h) {
		assert.Equal(t, "1", c.P(0))
		assert.Equal(t, "1", c.P(1))
	}

	h, _ = r.Find(GET, "/users/1", c)
	assert.Nil(t, h)
}
func TestCrawlFetch(t *testing.T) {
	// It should return the cast
	cast := <-crawl.fetch(testRSS)
	assert.NotNil(t, cast)
	assert.Equal(t, testRSS, cast.URL)
	assert.Equal(t, "BSD Now HD", cast.Name)

	// It should return nil if the url is bad
	assert.Nil(t, <-crawl.fetch("so_bad"))

	// It should return nil if the the status is not 200
	assert.Nil(t, <-crawl.fetch(testServer.URL))

	// It should return nil if it cant parse things
	assert.Nil(t, <-crawl.fetch(testServer.URL+"/notxml"))

	// It should return nil if the xml is not a proper feed
	assert.Nil(t, <-crawl.fetch(testServer.URL+"/notfeed"))
	assert.Nil(t, <-crawl.fetch(testServer.URL+"/badrss"))
	assert.Nil(t, <-crawl.fetch(testServer.URL+"/badatom"))
}
func TestRouterAPI(t *testing.T) {
	e := New()
	r := e.router

	for _, route := range api {
		r.Add(route.Method, route.Path, func(c *Context) error {
			return nil
		}, e)
	}
	c := NewContext(nil, nil, e)
	for _, route := range api {
		h, _ := r.Find(route.Method, route.Path, c)
		if assert.NotNil(t, h) {
			for i, n := range c.pnames {
				if assert.NotEmpty(t, n) {
					assert.Equal(t, ":"+n, c.P(i))
				}
			}
			h(c)
		}
	}
}
func TestGetUsers(t *testing.T) {
	users := store.GetUsers()
	assert.NotNil(t, users)
	assert.Equal(t, "test", users[0].Username)
}
func TestRouterPriority(t *testing.T) {
	e := New()
	r := e.router

	// Routes
	r.Add(GET, "/users", func(c *Context) error {
		c.Set("a", 1)
		return nil
	}, e)
	r.Add(GET, "/users/new", func(c *Context) error {
		c.Set("b", 2)
		return nil
	}, e)
	r.Add(GET, "/users/:id", func(c *Context) error {
		c.Set("c", 3)
		return nil
	}, e)
	r.Add(GET, "/users/dew", func(c *Context) error {
		c.Set("d", 4)
		return nil
	}, e)
	r.Add(GET, "/users/:id/files", func(c *Context) error {
		c.Set("e", 5)
		return nil
	}, e)
	r.Add(GET, "/users/newsee", func(c *Context) error {
		c.Set("f", 6)
		return nil
	}, e)
	r.Add(GET, "/users/*", func(c *Context) error {
		c.Set("g", 7)
		return nil
	}, e)
	c := NewContext(nil, nil, e)

	// Route > /users
	h, _ := r.Find(GET, "/users", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 1, c.Get("a"))
	}

	// Route > /users/new
	h, _ = r.Find(GET, "/users/new", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 2, c.Get("b"))
	}

	// Route > /users/:id
	h, _ = r.Find(GET, "/users/1", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 3, c.Get("c"))
	}

	// Route > /users/dew
	h, _ = r.Find(GET, "/users/dew", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 4, c.Get("d"))
	}

	// Route > /users/:id/files
	h, _ = r.Find(GET, "/users/1/files", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 5, c.Get("e"))
	}

	// Route > /users/:id
	h, _ = r.Find(GET, "/users/news", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 3, c.Get("c"))
	}

	// Route > /users/*
	h, _ = r.Find(GET, "/users/joe/books", c)
	if assert.NotNil(t, h) {
		h(c)
		assert.Equal(t, 7, c.Get("g"))
		assert.Equal(t, "joe/books", c.Param("_name"))
	}
}
func TestCrawlFetchAtom(t *testing.T) {
	cast := <-crawl.fetch(testAtom)
	assert.NotNil(t, cast)
	assert.Equal(t, testAtom, cast.URL)
	assert.Equal(t, "Example Feed", cast.Name)
}