Skip to content

Commit 323fe02

Browse files
authored
Minor refactoring of test code (#20)
* Release 1.0.1 (#16) * Using the ClientOptions provided at App initialization to create the … (#12) * Using the ClientOptions provided at App initialization to create the HTTPClient in auth package. * Fixed context import * Updated test case * Fixing a test failure; Calling transport.NewHTTPClient() only when ctx and opts are available to avoid an unnecessary default credentials lookup. * Passing a non-nil context to AuthConfig during testing; Replacing Print+Exit calls with log.Fatal() (#13) * Bumped version to 1.0.1 (#15) * Moved integration/auth_test.go to its own package. Moved fileKeySource to auth_test.go * Testing for iss and sub headers of custom tokens
1 parent 5d761a6 commit 323fe02

File tree

4 files changed

+107
-86
lines changed

4 files changed

+107
-86
lines changed

auth/auth_test.go

Lines changed: 93 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package auth
1616

1717
import (
1818
"errors"
19+
"io/ioutil"
1920
"log"
2021
"os"
2122
"strings"
@@ -36,68 +37,6 @@ import (
3637
var client *Client
3738
var testIDToken string
3839

39-
func verifyCustomToken(t *testing.T, token string, expected map[string]interface{}) {
40-
h := &jwtHeader{}
41-
p := &customToken{}
42-
if err := decodeToken(token, client.ks, h, p); err != nil {
43-
t.Fatal(err)
44-
}
45-
46-
if h.Algorithm != "RS256" {
47-
t.Errorf("Algorithm: %q; want: 'RS256'", h.Algorithm)
48-
} else if h.Type != "JWT" {
49-
t.Errorf("Type: %q; want: 'JWT'", h.Type)
50-
} else if p.Aud != firebaseAudience {
51-
t.Errorf("Audience: %q; want: %q", p.Aud, firebaseAudience)
52-
}
53-
54-
for k, v := range expected {
55-
if p.Claims[k] != v {
56-
t.Errorf("Claim[%q]: %v; want: %v", k, p.Claims[k], v)
57-
}
58-
}
59-
}
60-
61-
func getIDToken(p mockIDTokenPayload) string {
62-
return getIDTokenWithKid("mock-key-id-1", p)
63-
}
64-
65-
func getIDTokenWithKid(kid string, p mockIDTokenPayload) string {
66-
pCopy := mockIDTokenPayload{
67-
"aud": client.projectID,
68-
"iss": "https://securetoken.google.com/" + client.projectID,
69-
"iat": time.Now().Unix() - 100,
70-
"exp": time.Now().Unix() + 3600,
71-
"sub": "1234567890",
72-
"admin": true,
73-
}
74-
for k, v := range p {
75-
pCopy[k] = v
76-
}
77-
h := defaultHeader()
78-
h.KeyID = kid
79-
token, err := encodeToken(client.snr, h, pCopy)
80-
if err != nil {
81-
log.Fatalln(err)
82-
}
83-
return token
84-
}
85-
86-
type mockIDTokenPayload map[string]interface{}
87-
88-
func (p mockIDTokenPayload) decode(s string) error {
89-
return decode(s, &p)
90-
}
91-
92-
type mockKeySource struct {
93-
keys []*publicKey
94-
err error
95-
}
96-
97-
func (t *mockKeySource) Keys() ([]*publicKey, error) {
98-
return t.keys, t.err
99-
}
100-
10140
func TestMain(m *testing.M) {
10241
var (
10342
err error
@@ -286,6 +225,98 @@ func TestCertificateRequestError(t *testing.T) {
286225
}
287226
}
288227

228+
func verifyCustomToken(t *testing.T, token string, expected map[string]interface{}) {
229+
h := &jwtHeader{}
230+
p := &customToken{}
231+
if err := decodeToken(token, client.ks, h, p); err != nil {
232+
t.Fatal(err)
233+
}
234+
235+
email, err := client.snr.Email()
236+
if err != nil {
237+
t.Fatal(err)
238+
}
239+
240+
if h.Algorithm != "RS256" {
241+
t.Errorf("Algorithm: %q; want: 'RS256'", h.Algorithm)
242+
} else if h.Type != "JWT" {
243+
t.Errorf("Type: %q; want: 'JWT'", h.Type)
244+
} else if p.Aud != firebaseAudience {
245+
t.Errorf("Audience: %q; want: %q", p.Aud, firebaseAudience)
246+
} else if p.Iss != email {
247+
t.Errorf("Issuer: %q; want: %q", p.Iss, email)
248+
} else if p.Sub != email {
249+
t.Errorf("Subject: %q; want: %q", p.Sub, email)
250+
}
251+
252+
for k, v := range expected {
253+
if p.Claims[k] != v {
254+
t.Errorf("Claim[%q]: %v; want: %v", k, p.Claims[k], v)
255+
}
256+
}
257+
}
258+
259+
func getIDToken(p mockIDTokenPayload) string {
260+
return getIDTokenWithKid("mock-key-id-1", p)
261+
}
262+
263+
func getIDTokenWithKid(kid string, p mockIDTokenPayload) string {
264+
pCopy := mockIDTokenPayload{
265+
"aud": client.projectID,
266+
"iss": "https://securetoken.google.com/" + client.projectID,
267+
"iat": time.Now().Unix() - 100,
268+
"exp": time.Now().Unix() + 3600,
269+
"sub": "1234567890",
270+
"admin": true,
271+
}
272+
for k, v := range p {
273+
pCopy[k] = v
274+
}
275+
h := defaultHeader()
276+
h.KeyID = kid
277+
token, err := encodeToken(client.snr, h, pCopy)
278+
if err != nil {
279+
log.Fatalln(err)
280+
}
281+
return token
282+
}
283+
284+
type mockIDTokenPayload map[string]interface{}
285+
286+
func (p mockIDTokenPayload) decode(s string) error {
287+
return decode(s, &p)
288+
}
289+
290+
// mockKeySource provides access to a set of in-memory public keys.
291+
type mockKeySource struct {
292+
keys []*publicKey
293+
err error
294+
}
295+
296+
func (t *mockKeySource) Keys() ([]*publicKey, error) {
297+
return t.keys, t.err
298+
}
299+
300+
// fileKeySource loads a set of public keys from the local file system.
301+
type fileKeySource struct {
302+
FilePath string
303+
CachedKeys []*publicKey
304+
}
305+
306+
func (f *fileKeySource) Keys() ([]*publicKey, error) {
307+
if f.CachedKeys == nil {
308+
certs, err := ioutil.ReadFile(f.FilePath)
309+
if err != nil {
310+
return nil, err
311+
}
312+
f.CachedKeys, err = parsePublicKeys(certs)
313+
if err != nil {
314+
return nil, err
315+
}
316+
}
317+
return f.CachedKeys, nil
318+
}
319+
289320
// aeKeySource provides access to the public keys associated with App Engine apps. This
290321
// is used in tests to verify custom tokens and mock ID tokens when they are signed with
291322
// App Engine private keys.

auth/crypto.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -146,25 +146,6 @@ func (k *httpKeySource) refreshKeys() error {
146146
return nil
147147
}
148148

149-
type fileKeySource struct {
150-
FilePath string
151-
CachedKeys []*publicKey
152-
}
153-
154-
func (f *fileKeySource) Keys() ([]*publicKey, error) {
155-
if f.CachedKeys == nil {
156-
certs, err := ioutil.ReadFile(f.FilePath)
157-
if err != nil {
158-
return nil, err
159-
}
160-
f.CachedKeys, err = parsePublicKeys(certs)
161-
if err != nil {
162-
return nil, err
163-
}
164-
}
165-
return f.CachedKeys, nil
166-
}
167-
168149
func findMaxAge(resp *http.Response) (*time.Duration, error) {
169150
cc := resp.Header.Get("cache-control")
170151
for _, value := range strings.Split(cc, ", ") {

integration/auth_test.go renamed to integration/auth/auth_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
package integration
15+
// Package auth contains integration tests for the firebase.google.com/go/auth package.
16+
package auth
1617

1718
import (
1819
"bytes"

integration/internal/internal.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
package internal
1717

1818
import (
19+
"go/build"
1920
"io/ioutil"
21+
"path/filepath"
2022
"strings"
2123

2224
"golang.org/x/net/context"
@@ -25,24 +27,30 @@ import (
2527
"google.golang.org/api/option"
2628
)
2729

28-
const certPath = "../testdata/integration_cert.json"
29-
const apiKeyPath = "../testdata/integration_apikey.txt"
30+
const certPath = "integration_cert.json"
31+
const apiKeyPath = "integration_apikey.txt"
32+
33+
// Resource returns the absolute path to the specified test resource file.
34+
func Resource(name string) string {
35+
p := []string{build.Default.GOPATH, "src", "firebase.google.com", "go", "testdata", name}
36+
return filepath.Join(p...)
37+
}
3038

3139
// NewTestApp creates a new App instance for integration tests.
3240
//
3341
// NewTestApp looks for a service account JSON file named integration_cert.json
3442
// in the testdata directory. This file is used to initialize the newly created
3543
// App instance.
3644
func NewTestApp(ctx context.Context) (*firebase.App, error) {
37-
return firebase.NewApp(ctx, nil, option.WithCredentialsFile(certPath))
45+
return firebase.NewApp(ctx, nil, option.WithCredentialsFile(Resource(certPath)))
3846
}
3947

4048
// APIKey fetches a Firebase API key for integration tests.
4149
//
4250
// APIKey reads the API key string from a file named integration_apikey.txt
4351
// in the testdata directory.
4452
func APIKey() (string, error) {
45-
b, err := ioutil.ReadFile(apiKeyPath)
53+
b, err := ioutil.ReadFile(Resource(apiKeyPath))
4654
if err != nil {
4755
return "", err
4856
}

0 commit comments

Comments
 (0)