token: extra numeric values + test TokenType case
+ Added tests for TokenType by checking case.
+ Added numeric conversion for float and integer like
values from token.Extra.
Change-Id: I0909a4458ed58e33428afbf40478a668d150dda7
Reviewed-on: https://go-review.googlesource.com/15156
Reviewed-by: Andrew Gerrand <adg@golang.org>
diff --git a/oauth2_test.go b/oauth2_test.go
index 2f7d731..a99d7a3 100644
--- a/oauth2_test.go
+++ b/oauth2_test.go
@@ -11,6 +11,7 @@
"io/ioutil"
"net/http"
"net/http/httptest"
+ "net/url"
"reflect"
"strconv"
"testing"
@@ -170,6 +171,54 @@
if scope != "user" {
t.Errorf("Unexpected value for scope: %v", scope)
}
+ expiresIn := tok.Extra("expires_in")
+ if expiresIn != float64(86400) {
+ t.Errorf("Unexpected non-numeric value for expires_in: %v", expiresIn)
+ }
+}
+
+func TestExtraValueRetrieval(t *testing.T) {
+ values := url.Values{}
+
+ kvmap := map[string]string{
+ "scope": "user", "token_type": "bearer", "expires_in": "86400.92",
+ "server_time": "1443571905.5606415", "referer_ip": "10.0.0.1",
+ "etag": "\"afZYj912P4alikMz_P11982\"", "request_id": "86400",
+ "untrimmed": " untrimmed ",
+ }
+
+ for key, value := range kvmap {
+ values.Set(key, value)
+ }
+
+ tok := Token{
+ raw: values,
+ }
+
+ scope := tok.Extra("scope")
+ if scope != "user" {
+ t.Errorf("Unexpected scope %v wanted \"user\"", scope)
+ }
+ serverTime := tok.Extra("server_time")
+ if serverTime != 1443571905.5606415 {
+ t.Errorf("Unexpected non-float64 value for server_time: %v", serverTime)
+ }
+ refererIp := tok.Extra("referer_ip")
+ if refererIp != "10.0.0.1" {
+ t.Errorf("Unexpected non-string value for referer_ip: %v", refererIp)
+ }
+ expires_in := tok.Extra("expires_in")
+ if expires_in != 86400.92 {
+ t.Errorf("Unexpected value for expires_in, wanted 86400 got %v", expires_in)
+ }
+ requestId := tok.Extra("request_id")
+ if requestId != int64(86400) {
+ t.Errorf("Unexpected non-int64 value for request_id: %v", requestId)
+ }
+ untrimmed := tok.Extra("untrimmed")
+ if untrimmed != " untrimmed " {
+ t.Errorf("Unexpected value for untrimmed, got %q expected \" untrimmed \"", untrimmed)
+ }
}
const day = 24 * time.Hour
diff --git a/token.go b/token.go
index ebbdddb..4e596f0 100644
--- a/token.go
+++ b/token.go
@@ -7,6 +7,7 @@
import (
"net/http"
"net/url"
+ "strconv"
"strings"
"time"
@@ -92,14 +93,28 @@
// Extra fields are key-value pairs returned by the server as a
// part of the token retrieval response.
func (t *Token) Extra(key string) interface{} {
- if vals, ok := t.raw.(url.Values); ok {
- // TODO(jbd): Cast numeric values to int64 or float64.
- return vals.Get(key)
- }
if raw, ok := t.raw.(map[string]interface{}); ok {
return raw[key]
}
- return nil
+
+ vals, ok := t.raw.(url.Values)
+ if !ok {
+ return nil
+ }
+
+ v := vals.Get(key)
+ switch s := strings.TrimSpace(v); strings.Count(s, ".") {
+ case 0: // Contains no "."; try to parse as int
+ if i, err := strconv.ParseInt(s, 10, 64); err == nil {
+ return i
+ }
+ case 1: // Contains a single "."; try to parse as float
+ if f, err := strconv.ParseFloat(s, 64); err == nil {
+ return f
+ }
+ }
+
+ return v
}
// expired reports whether the token is expired.
diff --git a/token_test.go b/token_test.go
index 739eeb2..8344329 100644
--- a/token_test.go
+++ b/token_test.go
@@ -41,6 +41,7 @@
}{
{name: "12 seconds", tok: &Token{Expiry: now.Add(12 * time.Second)}, want: false},
{name: "10 seconds", tok: &Token{Expiry: now.Add(expiryDelta)}, want: true},
+ {name: "-1 hour", tok: &Token{Expiry: now.Add(-1 * time.Hour)}, want: true},
}
for _, tc := range cases {
if got, want := tc.tok.expired(), tc.want; got != want {
@@ -48,3 +49,24 @@
}
}
}
+
+func TestTokenTypeMethod(t *testing.T) {
+ cases := []struct {
+ name string
+ tok *Token
+ want string
+ }{
+ {name: "bearer-mixed_case", tok: &Token{TokenType: "beAREr"}, want: "Bearer"},
+ {name: "default-bearer", tok: &Token{}, want: "Bearer"},
+ {name: "basic", tok: &Token{TokenType: "basic"}, want: "Basic"},
+ {name: "basic-capitalized", tok: &Token{TokenType: "Basic"}, want: "Basic"},
+ {name: "mac", tok: &Token{TokenType: "mac"}, want: "MAC"},
+ {name: "mac-caps", tok: &Token{TokenType: "MAC"}, want: "MAC"},
+ {name: "mac-mixed_case", tok: &Token{TokenType: "mAc"}, want: "MAC"},
+ }
+ for _, tc := range cases {
+ if got, want := tc.tok.Type(), tc.want; got != want {
+ t.Errorf("TokenType(%q) = %v; want %v", tc.name, got, want)
+ }
+ }
+}