Skip to content

Commit 8c7208a

Browse files
committed
test json marshal and unmarshal
1 parent 28e21e4 commit 8c7208a

File tree

3 files changed

+75
-11
lines changed

3 files changed

+75
-11
lines changed

deviceauth.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"net/http"
1010
"net/url"
1111
"strings"
12+
"time"
1213

1314
"golang.org/x/net/context/ctxhttp"
1415
)
@@ -20,17 +21,44 @@ const (
2021
errExpiredToken = "expired_token"
2122
)
2223

23-
type DeviceAuth struct {
24-
DeviceCode string `json:"device_code"`
25-
UserCode string `json:"user_code"`
26-
VerificationURI string `json:"verification_uri,verification_url"`
27-
VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
28-
ExpiresIn int `json:"expires_in"`
29-
Interval int `json:"interval,omitempty"`
24+
type DeviceAuthResponse struct {
25+
DeviceCode string `json:"device_code"`
26+
UserCode string `json:"user_code"`
27+
VerificationURI string `json:"verification_uri"`
28+
VerificationURIComplete string `json:"verification_uri_complete,omitempty"`
29+
Expiry time.Time `json:"expires_in"`
30+
Interval int `json:"interval,omitempty"`
3031
raw map[string]interface{}
3132
}
3233

33-
func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuth, error) {
34+
func (d DeviceAuthResponse) MarshalJSON() ([]byte, error) {
35+
type Alias DeviceAuthResponse
36+
return json.Marshal(&struct {
37+
ExpiresIn int64 `json:"expires_in"`
38+
*Alias
39+
}{
40+
ExpiresIn: int64(time.Until(d.Expiry).Seconds()),
41+
Alias: (*Alias)(&d),
42+
})
43+
44+
}
45+
46+
func (c *DeviceAuthResponse) UnmarshalJSON(data []byte) error {
47+
type Alias DeviceAuthResponse
48+
aux := &struct {
49+
ExpiresIn int64 `json:"expires_in"`
50+
*Alias
51+
}{
52+
Alias: (*Alias)(c),
53+
}
54+
if err := json.Unmarshal(data, &aux); err != nil {
55+
return err
56+
}
57+
c.Expiry = time.Now().UTC().Add(time.Second * time.Duration(aux.ExpiresIn))
58+
return nil
59+
}
60+
61+
func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAuthResponse, error) {
3462
req, err := http.NewRequest("POST", c.Endpoint.DeviceAuthURL, strings.NewReader(v.Encode()))
3563
if err != nil {
3664
return nil, err
@@ -54,7 +82,7 @@ func retrieveDeviceAuth(ctx context.Context, c *Config, v url.Values) (*DeviceAu
5482
}
5583
}
5684

57-
da := &DeviceAuth{}
85+
da := &DeviceAuthResponse{}
5886
err = json.Unmarshal(body, &da)
5987
if err != nil {
6088
return nil, fmt.Errorf("unmarshal %s", err)

deviceauth_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package oauth2
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
"time"
7+
8+
"github.com/google/go-cmp/cmp"
9+
"github.com/google/go-cmp/cmp/cmpopts"
10+
)
11+
12+
func TestDeviceAuthResponseMarshalJson(t *testing.T) {
13+
d := DeviceAuthResponse{Expiry: time.Now().Add(100 * time.Second)}
14+
gotBytes, err := json.Marshal(d)
15+
if err != nil {
16+
t.Fatal(err)
17+
}
18+
got := string(gotBytes)
19+
want := `{"expires_in":99,"device_code":"","user_code":"","verification_uri":""}`
20+
if got != want {
21+
t.Errorf("want=%s, got=%s", want, got)
22+
}
23+
}
24+
25+
func TestDeviceAuthResponseUnmarshalJson(t *testing.T) {
26+
data := []byte(`{"expires_in":100}`)
27+
want := DeviceAuthResponse{Expiry: time.Now().UTC().Add(100 * time.Second)}
28+
got := DeviceAuthResponse{}
29+
err := json.Unmarshal(data, &got)
30+
if err != nil {
31+
t.Fatal(err)
32+
}
33+
if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(DeviceAuthResponse{}), cmpopts.EquateApproxTime(time.Second)) {
34+
t.Errorf("want=%#v, got=%#v", want, got)
35+
}
36+
}

oauth2.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ func (c *Config) Exchange(ctx context.Context, code string, opts ...AuthCodeOpti
228228

229229
// AuthDevice returns a device auth struct which contains a device code
230230
// and authorization information provided for users to enter on another device.
231-
func (c *Config) AuthDevice(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuth, error) {
231+
func (c *Config) AuthDevice(ctx context.Context, opts ...AuthCodeOption) (*DeviceAuthResponse, error) {
232232
v := url.Values{
233233
"client_id": {c.ClientID},
234234
}
@@ -242,7 +242,7 @@ func (c *Config) AuthDevice(ctx context.Context, opts ...AuthCodeOption) (*Devic
242242
}
243243

244244
// Poll does a polling to exchange an device code for a token.
245-
func (c *Config) Poll(ctx context.Context, da *DeviceAuth, opts ...AuthCodeOption) (*Token, error) {
245+
func (c *Config) Poll(ctx context.Context, da *DeviceAuthResponse, opts ...AuthCodeOption) (*Token, error) {
246246
v := url.Values{
247247
"client_id": {c.ClientID},
248248
"grant_type": {"urn:ietf:params:oauth:grant-type:device_code"},

0 commit comments

Comments
 (0)