chromium/google_apis/google_api_keys_unittest.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

// Unit tests for implementation of google_api_keys namespace.
//
// Because the file deals with a lot of preprocessor defines and
// optionally includes an internal header, the way we test is by
// including the .cc file multiple times with different defines set.
// This is a little unorthodox, but it lets us test the behavior as
// close to unmodified as possible.

#include "google_apis/google_api_keys_unittest.h"

#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "build/branding_buildflags.h"
#include "build/build_config.h"
#include "google_apis/gaia/gaia_config.h"
#include "google_apis/gaia/gaia_switches.h"
#include "google_apis/google_api_keys.h"
#include "google_apis/google_api_keys_utils.h"

// The Win builders fail (with a linker crash) when trying to link unit_tests,
// and the Android builders complain about multiply defined symbols (likely they
// don't do name decoration as well as the Mac and Linux linkers). Building and
// running on other platforms should provide plenty of coverage since there are
// no platform-specific bits in this code.
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_WIN)

// We need to include everything included by google_api_keys.cc once
// at global scope so that things like STL and classes from base don't
// get defined when we re-include the google_api_keys.cc file
// below. We used to include that file in its entirety here, but that
// can cause problems if the linker decides the version of symbols
// from that file included here is the "right" version.

#include <stddef.h>

#include <string>

#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/strings/stringize_macros.h"
#include "base/version_info/channel.h"

#if BUILDFLAG(IS_APPLE)
#include "google_apis/google_api_keys_mac.h"
#endif

GoogleAPIKeysTest::GoogleAPIKeysTest() :{}

GoogleAPIKeysTest::~GoogleAPIKeysTest() {}

void GoogleAPIKeysTest::SetUp() {}

void GoogleAPIKeysTest::TearDown() {}

// This is the default baked-in value for OAuth IDs and secrets.
static const char kDummyToken[] =;

base::FilePath GetTestFilePath(const std::string& relative_path) {}

#if defined(USE_OFFICIAL_GOOGLE_API_KEYS)
// Test official build behavior, since we are in a checkout where this
// is possible.
namespace official_build {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

// Try setting some keys, these should be ignored since it's a build
// with official keys.
#define GOOGLE_API_KEY
#define GOOGLE_CLIENT_ID_MAIN

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace official_build

TEST_F(GoogleAPIKeysTest, OfficialKeys) {
  namespace testcase = official_build::google_apis;

  EXPECT_TRUE(testcase::HasAPIKeyConfigured());
  EXPECT_TRUE(testcase::HasOAuthClientConfigured());

  std::string api_key = testcase::g_api_key_cache.Get().api_key();
  std::string id_main = testcase::g_api_key_cache.Get().GetClientID(
      testcase::CLIENT_MAIN);
  std::string secret_main =
      testcase::g_api_key_cache.Get().GetClientSecret(testcase::CLIENT_MAIN);
  std::string id_remoting = testcase::g_api_key_cache.Get().GetClientID(
      testcase::CLIENT_REMOTING);
  std::string secret_remoting =
      testcase::g_api_key_cache.Get().GetClientSecret(
          testcase::CLIENT_REMOTING);
  std::string id_remoting_host = testcase::g_api_key_cache.Get().GetClientID(
      testcase::CLIENT_REMOTING_HOST);
  std::string secret_remoting_host =
      testcase::g_api_key_cache.Get().GetClientSecret(
          testcase::CLIENT_REMOTING_HOST);

  EXPECT_NE(0u, api_key.size());
  EXPECT_NE(DUMMY_API_TOKEN, api_key);
  EXPECT_NE("bogus api_key", api_key);
  EXPECT_NE(kDummyToken, api_key);

  EXPECT_NE(0u, id_main.size());
  EXPECT_NE(DUMMY_API_TOKEN, id_main);
  EXPECT_NE("bogus client_id_main", id_main);
  EXPECT_NE(kDummyToken, id_main);

  EXPECT_NE(0u, secret_main.size());
  EXPECT_NE(DUMMY_API_TOKEN, secret_main);
  EXPECT_NE(kDummyToken, secret_main);

  EXPECT_NE(0u, id_remoting.size());
  EXPECT_NE(DUMMY_API_TOKEN, id_remoting);
  EXPECT_NE(kDummyToken, id_remoting);

  EXPECT_NE(0u, secret_remoting.size());
  EXPECT_NE(DUMMY_API_TOKEN, secret_remoting);
  EXPECT_NE(kDummyToken, secret_remoting);

  EXPECT_NE(0u, id_remoting_host.size());
  EXPECT_NE(DUMMY_API_TOKEN, id_remoting_host);
  EXPECT_NE(kDummyToken, id_remoting_host);

  EXPECT_NE(0u, secret_remoting_host.size());
  EXPECT_NE(DUMMY_API_TOKEN, secret_remoting_host);
  EXPECT_NE(kDummyToken, secret_remoting_host);
}
#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING) ||
        // defined(USE_OFFICIAL_GOOGLE_API_KEYS)

// After this test, for the remainder of this compilation unit, we
// need official keys to not be used.
#undef BUILDFLAG_INTERNAL_CHROMIUM_BRANDING
#undef BUILDFLAG_INTERNAL_GOOGLE_CHROME_BRANDING
#define BUILDFLAG_INTERNAL_CHROMIUM_BRANDING()
#define BUILDFLAG_INTERNAL_GOOGLE_CHROME_BRANDING()
#undef USE_OFFICIAL_GOOGLE_API_KEYS

// Test the set of keys temporarily baked into Chromium by default.
namespace default_keys {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace default_keys

TEST_F(GoogleAPIKeysTest, DefaultKeys) {}

// Override a couple of keys, leave the rest default.
namespace override_some_keys {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY
#define GOOGLE_CLIENT_ID_REMOTING

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_some_keys

TEST_F(GoogleAPIKeysTest, OverrideSomeKeys) {}

// Override all keys.
namespace override_all_keys {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY
#define GOOGLE_CLIENT_ID_MAIN
#define GOOGLE_CLIENT_SECRET_MAIN
#define GOOGLE_CLIENT_ID_REMOTING
#define GOOGLE_CLIENT_SECRET_REMOTING
#define GOOGLE_CLIENT_ID_REMOTING_HOST
#define GOOGLE_CLIENT_SECRET_REMOTING_HOST

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_all_keys

TEST_F(GoogleAPIKeysTest, OverrideAllKeys) {}

// Override API key via an experiment feature.
namespace override_api_key_via_feature_without_param {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_api_key_via_feature_without_param

TEST_F(GoogleAPIKeysTest, OverrideApiKeyViaFeatureWithNoParamIsIgnored) {}

// Override API key via an experiment feature.
namespace override_api_key_via_feature {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_api_key_via_feature

TEST_F(GoogleAPIKeysTest, OverrideApiKeyViaFeature) {}

#if !BUILDFLAG(GOOGLE_CHROME_BRANDING)

// Override all keys using both preprocessor defines and environment
// variables.  The environment variables should win.
namespace override_all_keys_env {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY
#define GOOGLE_CLIENT_ID_MAIN
#define GOOGLE_CLIENT_SECRET_MAIN
#define GOOGLE_CLIENT_ID_REMOTING
#define GOOGLE_CLIENT_SECRET_REMOTING
#define GOOGLE_CLIENT_ID_REMOTING_HOST
#define GOOGLE_CLIENT_SECRET_REMOTING_HOST

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_all_keys_env

TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingEnvironment) {}

#endif  // !BUILDFLAG(GOOGLE_CHROME_BRANDING)

#if BUILDFLAG(IS_IOS)
// Override all keys using both preprocessor defines and setters.
// Setters should win.
namespace override_all_keys_setters {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY
#define GOOGLE_CLIENT_ID_MAIN
#define GOOGLE_CLIENT_SECRET_MAIN
#define GOOGLE_CLIENT_ID_REMOTING
#define GOOGLE_CLIENT_SECRET_REMOTING
#define GOOGLE_CLIENT_ID_REMOTING_HOST
#define GOOGLE_CLIENT_SECRET_REMOTING_HOST

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_all_keys_setters

TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingSetters) {
  namespace testcase = override_all_keys_setters::google_apis;

  std::string api_key("setter-API_KEY");
  testcase::SetAPIKey(api_key);

  std::string id_main("setter-ID_MAIN");
  std::string secret_main("setter-SECRET_MAIN");
  testcase::SetOAuth2ClientID(testcase::CLIENT_MAIN, id_main);
  testcase::SetOAuth2ClientSecret(testcase::CLIENT_MAIN, secret_main);

  std::string id_remoting("setter-ID_REMOTING");
  std::string secret_remoting("setter-SECRET_REMOTING");
  testcase::SetOAuth2ClientID(testcase::CLIENT_REMOTING, id_remoting);
  testcase::SetOAuth2ClientSecret(testcase::CLIENT_REMOTING, secret_remoting);

  std::string id_remoting_host("setter-ID_REMOTING_HOST");
  std::string secret_remoting_host("setter-SECRET_REMOTING_HOST");
  testcase::SetOAuth2ClientID(testcase::CLIENT_REMOTING_HOST, id_remoting_host);
  testcase::SetOAuth2ClientSecret(testcase::CLIENT_REMOTING_HOST,
                                  secret_remoting_host);

  EXPECT_TRUE(testcase::HasAPIKeyConfigured());
  EXPECT_TRUE(testcase::HasOAuthClientConfigured());

  EXPECT_EQ(api_key, testcase::GetAPIKey(::version_info::Channel::STABLE));
  EXPECT_EQ(api_key, testcase::GetAPIKey());

  EXPECT_EQ(id_main, testcase::GetOAuth2ClientID(testcase::CLIENT_MAIN));
  EXPECT_EQ(secret_main,
            testcase::GetOAuth2ClientSecret(testcase::CLIENT_MAIN));

  EXPECT_EQ(id_remoting,
            testcase::GetOAuth2ClientID(testcase::CLIENT_REMOTING));
  EXPECT_EQ(secret_remoting,
            testcase::GetOAuth2ClientSecret(testcase::CLIENT_REMOTING));

  EXPECT_EQ(id_remoting_host,
            testcase::GetOAuth2ClientID(testcase::CLIENT_REMOTING_HOST));
  EXPECT_EQ(secret_remoting_host,
            testcase::GetOAuth2ClientSecret(testcase::CLIENT_REMOTING_HOST));
}
#endif  // BUILDFLAG(IS_IOS)

// Override all keys using both preprocessor defines and gaia config.
// Config should win.
namespace override_all_keys_config {

// We start every test by creating a clean environment for the
// preprocessor defines used in google_api_keys.cc
#undef DUMMY_API_TOKEN
#undef GOOGLE_API_KEY
#undef GOOGLE_CLIENT_ID_MAIN
#undef GOOGLE_CLIENT_SECRET_MAIN
#undef GOOGLE_CLIENT_ID_REMOTING
#undef GOOGLE_CLIENT_SECRET_REMOTING
#undef GOOGLE_CLIENT_ID_REMOTING_HOST
#undef GOOGLE_CLIENT_SECRET_REMOTING_HOST
#undef GOOGLE_DEFAULT_CLIENT_ID
#undef GOOGLE_DEFAULT_CLIENT_SECRET

#define GOOGLE_API_KEY
#define GOOGLE_CLIENT_ID_MAIN
#define GOOGLE_CLIENT_SECRET_MAIN
#define GOOGLE_CLIENT_ID_REMOTING
#define GOOGLE_CLIENT_SECRET_REMOTING
#define GOOGLE_CLIENT_ID_REMOTING_HOST
#define GOOGLE_CLIENT_SECRET_REMOTING_HOST

// Undef include guard so things get defined again, within this namespace.
#undef GOOGLE_APIS_GOOGLE_API_KEYS_H_
#undef GOOGLE_APIS_INTERNAL_GOOGLE_CHROME_API_KEYS_
#include "google_apis/google_api_keys-inc.cc"

}  // namespace override_all_keys_config

TEST_F(GoogleAPIKeysTest, OverrideAllKeysUsingConfig) {}

#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_WIN)