Home | History | Annotate | Download | only in internal_api
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sync/internal_api/js_sync_encryption_handler_observer.h"
      6 
      7 #include "base/basictypes.h"
      8 #include "base/location.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "base/values.h"
     11 #include "sync/internal_api/public/base/model_type.h"
     12 #include "sync/internal_api/public/util/sync_string_conversions.h"
     13 #include "sync/internal_api/public/util/weak_handle.h"
     14 #include "sync/js/js_event_details.h"
     15 #include "sync/js/js_test_util.h"
     16 #include "sync/test/fake_encryptor.h"
     17 #include "sync/util/cryptographer.h"
     18 #include "sync/util/time.h"
     19 #include "testing/gtest/include/gtest/gtest.h"
     20 
     21 namespace syncer {
     22 namespace {
     23 
     24 using ::testing::InSequence;
     25 using ::testing::StrictMock;
     26 
     27 class JsSyncEncryptionHandlerObserverTest : public testing::Test {
     28  protected:
     29   JsSyncEncryptionHandlerObserverTest() {
     30     js_sync_encryption_handler_observer_.SetJsEventHandler(
     31         mock_js_event_handler_.AsWeakHandle());
     32   }
     33 
     34  private:
     35   // This must be destroyed after the member variables below in order
     36   // for WeakHandles to be destroyed properly.
     37   base::MessageLoop message_loop_;
     38 
     39  protected:
     40   StrictMock<MockJsEventHandler> mock_js_event_handler_;
     41   JsSyncEncryptionHandlerObserver js_sync_encryption_handler_observer_;
     42 
     43   void PumpLoop() {
     44     message_loop_.RunUntilIdle();
     45   }
     46 };
     47 
     48 TEST_F(JsSyncEncryptionHandlerObserverTest, NoArgNotifiations) {
     49   InSequence dummy;
     50 
     51   EXPECT_CALL(mock_js_event_handler_,
     52               HandleJsEvent("onEncryptionComplete",
     53                             HasDetails(JsEventDetails())));
     54 
     55   js_sync_encryption_handler_observer_.OnEncryptionComplete();
     56   PumpLoop();
     57 }
     58 
     59 TEST_F(JsSyncEncryptionHandlerObserverTest, OnPassphraseRequired) {
     60   InSequence dummy;
     61 
     62   base::DictionaryValue reason_passphrase_not_required_details;
     63   base::DictionaryValue reason_encryption_details;
     64   base::DictionaryValue reason_decryption_details;
     65 
     66   reason_passphrase_not_required_details.SetString(
     67       "reason",
     68       PassphraseRequiredReasonToString(REASON_PASSPHRASE_NOT_REQUIRED));
     69   reason_encryption_details.SetString(
     70       "reason",
     71       PassphraseRequiredReasonToString(REASON_ENCRYPTION));
     72   reason_decryption_details.SetString(
     73       "reason",
     74       PassphraseRequiredReasonToString(REASON_DECRYPTION));
     75 
     76   EXPECT_CALL(mock_js_event_handler_,
     77               HandleJsEvent("onPassphraseRequired",
     78                            HasDetailsAsDictionary(
     79                                reason_passphrase_not_required_details)));
     80   EXPECT_CALL(mock_js_event_handler_,
     81               HandleJsEvent("onPassphraseRequired",
     82                            HasDetailsAsDictionary(reason_encryption_details)));
     83   EXPECT_CALL(mock_js_event_handler_,
     84               HandleJsEvent("onPassphraseRequired",
     85                            HasDetailsAsDictionary(reason_decryption_details)));
     86 
     87   js_sync_encryption_handler_observer_.OnPassphraseRequired(
     88       REASON_PASSPHRASE_NOT_REQUIRED,
     89       sync_pb::EncryptedData());
     90   js_sync_encryption_handler_observer_.OnPassphraseRequired(REASON_ENCRYPTION,
     91                                                  sync_pb::EncryptedData());
     92   js_sync_encryption_handler_observer_.OnPassphraseRequired(REASON_DECRYPTION,
     93                                                  sync_pb::EncryptedData());
     94   PumpLoop();
     95 }
     96 
     97 TEST_F(JsSyncEncryptionHandlerObserverTest, OnBootstrapTokenUpdated) {
     98   base::DictionaryValue bootstrap_token_details;
     99   bootstrap_token_details.SetString("bootstrapToken", "<redacted>");
    100   bootstrap_token_details.SetString("type", "PASSPHRASE_BOOTSTRAP_TOKEN");
    101 
    102   EXPECT_CALL(mock_js_event_handler_,
    103               HandleJsEvent(
    104                   "onBootstrapTokenUpdated",
    105                   HasDetailsAsDictionary(bootstrap_token_details)));
    106 
    107   js_sync_encryption_handler_observer_.OnBootstrapTokenUpdated(
    108       "sensitive_token", PASSPHRASE_BOOTSTRAP_TOKEN);
    109   PumpLoop();
    110 }
    111 
    112 TEST_F(JsSyncEncryptionHandlerObserverTest, OnEncryptedTypesChanged) {
    113   base::DictionaryValue expected_details;
    114   base::ListValue* encrypted_type_values = new base::ListValue();
    115   const bool encrypt_everything = false;
    116   expected_details.Set("encryptedTypes", encrypted_type_values);
    117   expected_details.SetBoolean("encryptEverything", encrypt_everything);
    118   ModelTypeSet encrypted_types;
    119 
    120   for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) {
    121     ModelType type = ModelTypeFromInt(i);
    122     encrypted_types.Put(type);
    123     encrypted_type_values->Append(new base::StringValue(
    124         ModelTypeToString(type)));
    125   }
    126 
    127   EXPECT_CALL(mock_js_event_handler_,
    128               HandleJsEvent("onEncryptedTypesChanged",
    129                             HasDetailsAsDictionary(expected_details)));
    130 
    131   js_sync_encryption_handler_observer_.OnEncryptedTypesChanged(
    132       encrypted_types, encrypt_everything);
    133   PumpLoop();
    134 }
    135 
    136 
    137 TEST_F(JsSyncEncryptionHandlerObserverTest, OnCryptographerStateChanged) {
    138   base::DictionaryValue expected_details;
    139   bool expected_ready = false;
    140   bool expected_pending = false;
    141   expected_details.SetBoolean("ready", expected_ready);
    142   expected_details.SetBoolean("hasPendingKeys", expected_pending);
    143   ModelTypeSet encrypted_types;
    144 
    145   EXPECT_CALL(mock_js_event_handler_,
    146               HandleJsEvent("onCryptographerStateChanged",
    147                             HasDetailsAsDictionary(expected_details)));
    148 
    149   FakeEncryptor encryptor;
    150   Cryptographer cryptographer(&encryptor);
    151 
    152   js_sync_encryption_handler_observer_.OnCryptographerStateChanged(
    153       &cryptographer);
    154   PumpLoop();
    155 }
    156 
    157 TEST_F(JsSyncEncryptionHandlerObserverTest, OnPassphraseTypeChanged) {
    158   InSequence dummy;
    159 
    160   base::DictionaryValue passphrase_type_details;
    161   passphrase_type_details.SetString("passphraseType", "IMPLICIT_PASSPHRASE");
    162   passphrase_type_details.SetInteger("explicitPassphraseTime", 10);
    163   EXPECT_CALL(mock_js_event_handler_,
    164               HandleJsEvent("onPassphraseTypeChanged",
    165                             HasDetailsAsDictionary(passphrase_type_details)));
    166 
    167   js_sync_encryption_handler_observer_.OnPassphraseTypeChanged(
    168       IMPLICIT_PASSPHRASE, ProtoTimeToTime(10));
    169   PumpLoop();
    170 }
    171 
    172 }  // namespace
    173 }  // namespace syncer
    174