github.com/actions-on-google/gactions@v3.2.0+incompatible/api/apiutils_test.go (about) 1 // Copyright 2020 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package apiutils 16 17 import ( 18 "context" 19 "encoding/json" 20 "io/ioutil" 21 "os" 22 "path" 23 "path/filepath" 24 "testing" 25 26 "github.com/actions-on-google/gactions/api/testutils" 27 "github.com/google/go-cmp/cmp" 28 "github.com/google/go-cmp/cmp/cmpopts" 29 "golang.org/x/oauth2" 30 ) 31 32 func TestRemoveTokenExists(t *testing.T) { 33 ogTCF := tokenCacheFile 34 ogRT := revokeToken 35 t.Cleanup(func() { 36 tokenCacheFile = ogTCF 37 revokeToken = ogRT 38 }) 39 d, err := ioutil.TempDir(testutils.TestTmpDir, ".credentials") 40 if err != nil { 41 t.Errorf("Failed to create a temp dir: got %v", err) 42 } 43 f, err := ioutil.TempFile(d, "test-creds") 44 if err != nil { 45 t.Errorf("Failed to create a temp file: got %v", err) 46 } 47 defer func() { 48 os.RemoveAll(d) 49 }() 50 if err := f.Close(); err != nil { 51 t.Errorf("Failed to close the file: got %v", err) 52 } 53 tokenCacheFile = func() (string, error) { 54 return f.Name(), nil 55 } 56 revokeToken = func(tokenFile []byte) error { 57 return nil 58 } 59 if err := RemoveTokenWithFilename(f.Name()); err != nil { 60 t.Errorf("RemoveTokenWithFilename returned %v, want %v", err, nil) 61 } 62 } 63 64 func TestRemoveTokenDoesNotExist(t *testing.T) { 65 if err := RemoveToken(); err == nil { 66 t.Error("RemoveToken returned %v, want error", err) 67 } 68 } 69 70 func createCachedTokenFile(cachedToken *oauth2.Token) (string, string, error) { 71 dirName, err := ioutil.TempDir(testutils.TestTmpDir, ".credentials") 72 if err != nil { 73 return "", "", err 74 } 75 cachedTokenBytes, _ := json.Marshal(cachedToken) 76 err = ioutil.WriteFile(path.Join(dirName, "gactions-test-secret.json"), cachedTokenBytes, 0644) 77 return dirName, path.Join(dirName, "gactions-test-secret.json"), err 78 } 79 80 func TestTokenWhenCachedTokenExists(t *testing.T) { 81 cachedToken := oauth2.Token{ 82 AccessToken: "123", 83 RefreshToken: "456", 84 } 85 conf := oauth2.Config{} 86 cachedFileDir, cachedFilename, err := createCachedTokenFile(&cachedToken) 87 defer os.RemoveAll(cachedFileDir) 88 if err != nil { 89 t.Fatalf("Can't create temporary files under %q: %v", cachedFilename, err) 90 } 91 tok, err := token(context.Background(), &conf, cachedFilename, false) 92 if err != nil { 93 t.Errorf("GetToken returned %v, but want %v", err, nil) 94 } 95 if *tok != cachedToken { 96 t.Errorf("GetToken returns %v when the cached token is %v", *tok, cachedToken) 97 } 98 } 99 100 func TestTokenWhenCachedTokenDoesNotExist(t *testing.T) { 101 cachedToken := oauth2.Token{ 102 AccessToken: "123", 103 RefreshToken: "456", 104 } 105 conf := oauth2.Config{} 106 originalFn := interactiveTokenCopyPaste 107 interactiveTokenCopyPaste = func(ctx context.Context, conf *oauth2.Config) (*oauth2.Token, error) { 108 return &cachedToken, nil 109 } 110 defer func() { 111 interactiveTokenCopyPaste = originalFn 112 }() 113 tok, err := token(context.Background(), &conf, "", false) 114 if err != nil { 115 t.Errorf("GetToken returned %v, but want %v", err, nil) 116 } 117 if *tok != cachedToken { 118 t.Errorf("GetToken returns %v when the cached token is %v", *tok, cachedToken) 119 } 120 } 121 122 func TestNewHTTPClientWhenCachedTokenDoesNotExist(t *testing.T) { 123 // Pass in a null token file 124 _, err := NewHTTPClient(context.Background(), []byte(`{"installed":{"redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}`), "/tmp/token") 125 if err == nil { 126 t.Errorf("NewHTTPClient should throw an error when the cached token does not exist") 127 } 128 } 129 130 func TestAuthSavesToken(t *testing.T) { 131 originalToken := token 132 originalCacheFile := tokenCacheFile 133 defer func() { 134 token = originalToken 135 tokenCacheFile = originalCacheFile 136 }() 137 want := oauth2.Token{ 138 AccessToken: "123", 139 RefreshToken: "456", 140 } 141 token = func(ctx context.Context, config *oauth2.Config, tokenCacheFilename string, launch bool) (*oauth2.Token, error) { 142 return &want, nil 143 } 144 d, err := ioutil.TempDir(testutils.TestTmpDir, ".credentials") 145 if err != nil { 146 t.Fatalf("Failed to create a temporary directory: got %v", err) 147 } 148 defer os.RemoveAll(d) 149 tokenCacheFile = func() (string, error) { 150 return filepath.Join(d, "file.json"), nil 151 } 152 err = Auth(context.Background(), []byte(`{"installed":{"redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}`)) 153 if err != nil { 154 t.Errorf("Auth returned %v, but want %v", err, nil) 155 } 156 b, err := ioutil.ReadFile(filepath.Join(d, "file.json")) 157 if err != nil { 158 t.Errorf("Failed to read a file containing the token created by Auth: got %v", err) 159 } 160 var got oauth2.Token 161 if err := json.Unmarshal(b, &got); err != nil { 162 t.Errorf("Auth should have written a syntactically correct JSON, but got %v", err) 163 } 164 if !cmp.Equal(got, want, cmpopts.IgnoreUnexported(oauth2.Token{})) { 165 t.Errorf("Auth should have saved %v to disc, but wrote %v instead", want, got) 166 } 167 }