func TestNewAccessToken(t *testing.T) {
	var (
		client      = &models.OauthClient{Model: gorm.Model{ID: 1}}
		user        = &models.OauthUser{Model: gorm.Model{ID: 2}}
		accessToken *models.OauthAccessToken
		v           driver.Value
		err         error
	)

	// When user object is nil
	accessToken = models.NewOauthAccessToken(
		client, // client
		nil,    // user
		3600,   // expires in
		"scope doesn't matter", // scope
	)

	// accessToken.ClientID.Valid should be true
	assert.True(t, accessToken.ClientID.Valid)

	// accessToken.ClientID.Value() should return the object id, in this case int64(1)
	v, err = accessToken.ClientID.Value()
	assert.Nil(t, err)
	assert.Equal(t, int64(1), v)

	// accessToken.UserID.Valid should be false
	assert.False(t, accessToken.UserID.Valid)

	// accessToken.UserID.Value() should return nil
	v, err = accessToken.UserID.Value()
	assert.Nil(t, err)
	assert.Nil(t, v)

	// When user object is not nil
	accessToken = models.NewOauthAccessToken(
		client, // client
		user,   // user
		3600,   // expires in
		"scope doesn't matter", // scope
	)

	// accessToken.ClientID.Valid should be true
	assert.True(t, accessToken.ClientID.Valid)

	// accessToken.ClientID.Value() should return the object id, in this case int64(1)
	v, err = accessToken.ClientID.Value()
	assert.Nil(t, err)
	assert.Equal(t, int64(1), v)

	// accessToken.UserID.Valid should be true
	assert.True(t, accessToken.UserID.Valid)

	// accessToken.UserID.Value() should return the object id, in this case int64(2)
	v, err = accessToken.UserID.Value()
	assert.Nil(t, err)
	assert.Equal(t, int64(2), v)
}
// GrantAccessToken deletes old tokens and grants a new access token
func (s *Service) GrantAccessToken(client *models.OauthClient, user *models.OauthUser, expiresIn int, scope string) (*models.OauthAccessToken, error) {
	// Begin a transaction
	tx := s.db.Begin()

	// Delete expired access tokens
	query := tx.Unscoped().Where("client_id = ?", client.ID)
	if user != nil && user.ID > 0 {
		query = query.Where("user_id = ?", user.ID)
	} else {
		query = query.Where("user_id IS NULL")
	}
	if err := query.Where("expires_at <= ?", time.Now()).Delete(new(models.OauthAccessToken)).Error; err != nil {
		tx.Rollback() // rollback the transaction
		return nil, err
	}

	// Create a new access token
	accessToken := models.NewOauthAccessToken(client, user, expiresIn, scope)
	if err := tx.Create(accessToken).Error; err != nil {
		tx.Rollback() // rollback the transaction
		return nil, err
	}
	accessToken.Client = client
	accessToken.User = user

	// Commit the transaction
	if err := tx.Commit().Error; err != nil {
		tx.Rollback() // rollback the transaction
		return nil, err
	}

	return accessToken, nil
}