// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package xsrftoken

import (
	"encoding/base64"
	"testing"
	"time"
)

const (
	key      = "quay"
	userID   = "12345678"
	actionID = "POST /form"
)

var (
	now              = time.Now()
	oneMinuteFromNow = now.Add(1 * time.Minute)
)

func TestValidToken(t *testing.T) {
	tok := generateTokenAtTime(key, userID, actionID, now)
	if !validTokenAtTime(tok, key, userID, actionID, oneMinuteFromNow) {
		t.Error("One second later: Expected token to be valid")
	}
	if !validTokenAtTime(tok, key, userID, actionID, now.Add(Timeout-1*time.Nanosecond)) {
		t.Error("Just before timeout: Expected token to be valid")
	}
	if !validTokenAtTime(tok, key, userID, actionID, now.Add(-1*time.Minute+1*time.Millisecond)) {
		t.Error("One minute in the past: Expected token to be valid")
	}
}

// TestSeparatorReplacement tests that separators are being correctly substituted
func TestSeparatorReplacement(t *testing.T) {
	separatorTests := []struct {
		name   string
		token1 string
		token2 string
	}{
		{
			"Colon",
			generateTokenAtTime("foo:bar", "baz", "wah", now),
			generateTokenAtTime("foo", "bar:baz", "wah", now),
		},
		{
			"Colon and Underscore",
			generateTokenAtTime("key", ":foo:", "wah", now),
			generateTokenAtTime("key", "_foo_", "wah", now),
		},
		{
			"Colon and Double Colon",
			generateTokenAtTime("key", ":foo:", "wah", now),
			generateTokenAtTime("key", "::foo::", "wah", now),
		},
	}

	for _, st := range separatorTests {
		if st.token1 == st.token2 {
			t.Errorf("%v: Expected generated tokens to be different", st.name)
		}
	}
}

func TestInvalidToken(t *testing.T) {
	invalidTokenTests := []struct {
		name, key, userID, actionID string
		t                           time.Time
	}{
		{"Bad key", "foobar", userID, actionID, oneMinuteFromNow},
		{"Bad userID", key, "foobar", actionID, oneMinuteFromNow},
		{"Bad actionID", key, userID, "foobar", oneMinuteFromNow},
		{"Expired", key, userID, actionID, now.Add(Timeout + 1*time.Millisecond)},
		{"More than 1 minute from the future", key, userID, actionID, now.Add(-1*time.Nanosecond - 1*time.Minute)},
	}

	tok := generateTokenAtTime(key, userID, actionID, now)
	for _, itt := range invalidTokenTests {
		if validTokenAtTime(tok, itt.key, itt.userID, itt.actionID, itt.t) {
			t.Errorf("%v: Expected token to be invalid", itt.name)
		}
	}
}

// TestValidateBadData primarily tests that no unexpected panics are triggered
// during parsing
func TestValidateBadData(t *testing.T) {
	badDataTests := []struct {
		name, tok string
	}{
		{"Invalid Base64", "ASDab24(@)$*=="},
		{"No delimiter", base64.URLEncoding.EncodeToString([]byte("foobar12345678"))},
		{"Invalid time", base64.URLEncoding.EncodeToString([]byte("foobar:foobar"))},
		{"Wrong length", "1234" + generateTokenAtTime(key, userID, actionID, now)},
	}

	for _, bdt := range badDataTests {
		if validTokenAtTime(bdt.tok, key, userID, actionID, oneMinuteFromNow) {
			t.Errorf("%v: Expected token to be invalid", bdt.name)
		}
	}
}
