You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: token_test.go
    path of file: ./repos/rancher/pkg/controllers/managementuser/clusterauthtoken
    
    the code of the file until where you have to start completion: package clusterauthtoken

import (
	"fmt"
	"testing"

	clusterv3 "github.com/rancher/rancher/pkg/apis/cluster.cattle.io/v3"
	v3 "github.com/rancher/rancher/pkg/apis/management.cattle.io/v3"
	"github.com/rancher/rancher/pkg/auth/tokens"
	"github.com/rancher/rancher/pkg/auth/tokens/hashers"
	"github.com/rancher/rancher/pkg/features"
	"github.com/rancher/rancher/pkg/generate
    
func TestUpdate(t *testing.T) {
	testToken := &managementv3.Token{
		ObjectMeta: metav1.ObjectMeta{
			Name: "test-token",
		},
		ExpiresAt: "10000000000",
		UserID:    userID,
		Token:     tokenKey,
		Enabled:   pointer.Bool(true),
	}

	testAuthToken := &clusterv3.ClusterAuthToken{
		ObjectMeta: metav1.ObjectMeta{
			Name: "test-token",
		},
		TypeMeta: metav1.TypeMeta{
			Kind: "ClusterAuthToken",
		},
		ExpiresAt:     "10000000000",
		UserName:      userID,
		SecretKeyHash: hashedTokenKey,
		Enabled:       true,
	}
	oldAuthToken := testAuthToken.DeepCopy()
	oldAuthToken.SecretKeyHash = legacyHashedTokenKey

	authTokenNotFoundError := apierrors.NewNotFound(schema.GroupResource{Group: "cluster.cattle.io", Resource: "ClusterAuthToken"}, testToken.Name)
	tests := []struct {
		name  string
		token *managementv3.Token

		existingClusterAuthToken *clusterv3.ClusterAuthToken
		existingTokenError       error
		tokenHashingEnabled      bool
		updateAuthTokenErr       error
		createAuthTokenErr       error

		wantClusterAuthToken bool
		wantAuthTokenUpdate  bool
		wantAuthTokenEnabled bool
		wantError            bool
		wantSkipError        bool
	}{

		{
			name:                     "token disabled, update token",
			token:                    setTokenEnabled(testToken, pointer.Bool(false)),
			existingClusterAuthToken: testAuthToken,

			wantClusterAuthToken: true,
			wantAuthTokenEnabled: false,
			wantAuthTokenUpdate:  true,
		},
		{
			name:                     "token enabled missing, no token update",
			token:                    setTokenEnabled(testToken, nil),
			existingClusterAuthToken: testAuthToken,

			wantClusterAuthToken: false,
		},
		{
			name:                     "token expiry change, update token",
			token:                    setTokenExpiry(testToken, "2000"),
			existingClusterAuthToken: testAuthToken,

			wantClusterAuthToken: true,
			wantAuthTokenUpdate:  true,
			wantAuthTokenEnabled: true,
		},
		{
			name:                     "token username change, update token",
			token:                    setTokenUser(testToken, "new-user"),
			existingClusterAuthToken: testAuthToken,

			wantClusterAuthToken: true,
			wantAuthTokenUpdate:  true,
			wantAuthTokenEnabled: true,
		},
		{
			name:                     "token hash change sha3, update token",
			token:                    hashToken(testToken, hashedTokenKey),
			existingClusterAuthToken: oldAuthToken,
			tokenHashingEnabled:      true,

			wantClusterAuthToken: true,
			wantAuthTokenUpdate:  true,
			wantAuthTokenEnabled: true,
		},
		{
			name:                     "token hash change non-sha3, don't update token",
			token:                    hashToken(testToken, legacyHashedTokenKey),
			existingClusterAuthToken: testAuthToken,
			tokenHashingEnabled:      true,

			wantClusterAuthToken: false,
		},
		{
			name:                     "no change, don't update",
			token:                    testToken,
			existingClusterAuthToken: testAuthToken,

			wantClusterAuthToken: false,
		},
		{
			name:                "token hashing disabled, create token",
			token:               testToken,
			existingTokenError:  authTokenNotFoundError,
			tokenHashingEnabled: false,

			wantClusterAuthToken: true,
			wantAuthTokenEnabled: true,
		},
		{
			name:               "get current token error",
			token:              testToken,
			existingTokenError: fmt.Errorf("server not available"),

			wantError: true,
		},
		{
			name:                     "invalid token hash version",
			token:                    hashToken(testToken, invalidHashKey),
			existingClusterAuthToken: testAuthToken,
			tokenHashingEnabled:      true,

			wantError:     true,
			wantSkipError: true,
		},
		{
			name:                     "update auth token error",
			token:                    setTokenUser(testToken, "new-user"),
			existingClusterAuthToken: testAuthToken,
			updateAuthTokenErr:       fmt.Errorf("server unavailable"),

			wantError:            true,
			wantAuthTokenUpdate:  true,
			wantClusterAuthToken: true,
			wantAuthTokenEnabled: true,
		},
		{
			name:                     "update auth token not found, create token success",
			token:                    setTokenUser(testToken, "new-user"),
			existingClusterAuthToken: testAuthToken,
			updateAuthTokenErr:       authTokenNotFoundError,

			wantClusterAuthToken: true,
			wantAuthTokenUpdate:  true,
			wantAuthTokenEnabled: true,
		},
		{
			name:                     "update auth token not found, create token error",
			token:                    setTokenUser(testToken, "new-user"),
			existingClusterAuthToken: testAuthToken,
			updateAuthTokenErr:       authTokenNotFoundError,
			createAuthTokenErr:       fmt.Errorf("server not available"),

			wantError:            true,
			wantClusterAuthToken: true,
			wantAuthTokenUpdate:  true,
			wantAuthTokenEnabled: true,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			output := runCreateUpdateTest(t, &testInput{
				Token:                    test.token,
				ExistingClusterAuthToken: test.existingClusterAuthToken,
				ExistingTokenError:       test.existingTokenError,
				TokenHashingEnabled:      test.tokenHashingEnabled,
				UpdateAuthTokenErr:       test.updateAuthTokenErr,
				CreateAuthTokenErr:       test.createAuthTokenErr,
				CallCreate:               false,
			})
			if test.wantError {
				require.Error(t, output.Error)
				if test.wantSkipError {
					require.ErrorIs(t, generic.ErrSkip, output.Error)
				} else {
					require.NotErrorIs(t, generic.ErrSkip, output.Error)
				}
			} else {
				require.NoError(t, output.Error)
			}
			if test.wantClusterAuthToken {
				modifiedToken := output.ModifiedClusterAuthToken
				require.NotNil(t, modifiedToken)
				require.Equal(t, test.wantAuthTokenUpdate, output.AuthTokenUpdated)

				require.Equal(t, "ClusterAuthToken", modifiedToken.Kind)
				require.Equal(t, test.token.Name, modifiedToken.Name)
				require.Equal(t, test.token.UserID, modifiedToken.UserName)
				require.Equal(t, test.token.ExpiresAt, modifiedToken.ExpiresAt)
				require.Equal(t, test.wantAuthTokenEnabled, modifiedToken.Enabled)

				if test.tokenHashingEnabled {
					// if tokenHashing is enabled hash should be the same on the token and cluster auth token
					require.Equal(t, test.token.Token, modifiedToken.SecretKeyHash)
				} else {
					// if tokenHashing is not enabled, the clusterAuthToken will be hashed but the token won't be
					// so we verify that the cluster auth token is a valid hash for the token
					hashedToken := modifiedToken.SecretKeyHash
					hasher, err := hashers.GetHasherForHash(hashedToken)
					require.NoError(t, err)
					require.NoError(t, hasher.VerifyHash(hashedToken, test.token.Token))
				}
			} else {
				require.Nil(t, output.ModifiedClusterAuthToken)
			}
		})
	}
}