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_mutation_event_observer.h" 6 7 #include "base/basictypes.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/values.h" 10 #include "sync/internal_api/public/base/model_type.h" 11 #include "sync/internal_api/public/util/weak_handle.h" 12 #include "sync/js/js_event_details.h" 13 #include "sync/js/js_test_util.h" 14 #include "testing/gtest/include/gtest/gtest.h" 15 16 namespace syncer { 17 namespace { 18 19 using ::testing::InSequence; 20 using ::testing::StrictMock; 21 22 class JsMutationEventObserverTest : public testing::Test { 23 protected: 24 JsMutationEventObserverTest() { 25 js_mutation_event_observer_.SetJsEventHandler( 26 mock_js_event_handler_.AsWeakHandle()); 27 } 28 29 private: 30 // This must be destroyed after the member variables below in order 31 // for WeakHandles to be destroyed properly. 32 base::MessageLoop message_loop_; 33 34 protected: 35 StrictMock<MockJsEventHandler> mock_js_event_handler_; 36 JsMutationEventObserver js_mutation_event_observer_; 37 38 void PumpLoop() { 39 message_loop_.RunUntilIdle(); 40 } 41 }; 42 43 TEST_F(JsMutationEventObserverTest, OnChangesApplied) { 44 InSequence dummy; 45 46 // We don't test with passwords as that requires additional setup. 47 48 // Build a list of example ChangeRecords. 49 ChangeRecord changes[MODEL_TYPE_COUNT]; 50 for (int i = AUTOFILL_PROFILE; i < MODEL_TYPE_COUNT; ++i) { 51 changes[i].id = i; 52 switch (i % 3) { 53 case 0: 54 changes[i].action = ChangeRecord::ACTION_ADD; 55 break; 56 case 1: 57 changes[i].action = ChangeRecord::ACTION_UPDATE; 58 break; 59 default: 60 changes[i].action = ChangeRecord::ACTION_DELETE; 61 break; 62 } 63 } 64 65 // For each i, we call OnChangesApplied() with the first arg equal 66 // to i cast to ModelType and the second argument with the changes 67 // starting from changes[i]. 68 69 // Set expectations for each data type. 70 for (int i = AUTOFILL_PROFILE; i < MODEL_TYPE_COUNT; ++i) { 71 const std::string& model_type_str = 72 ModelTypeToString(ModelTypeFromInt(i)); 73 base::DictionaryValue expected_details; 74 expected_details.SetString("modelType", model_type_str); 75 expected_details.SetString("writeTransactionId", "0"); 76 base::ListValue* expected_changes = new base::ListValue(); 77 expected_details.Set("changes", expected_changes); 78 for (int j = i; j < MODEL_TYPE_COUNT; ++j) { 79 expected_changes->Append(changes[j].ToValue()); 80 } 81 EXPECT_CALL(mock_js_event_handler_, 82 HandleJsEvent("onChangesApplied", 83 HasDetailsAsDictionary(expected_details))); 84 } 85 86 // Fire OnChangesApplied() for each data type. 87 for (int i = AUTOFILL_PROFILE; i < MODEL_TYPE_COUNT; ++i) { 88 ChangeRecordList local_changes(changes + i, changes + arraysize(changes)); 89 js_mutation_event_observer_.OnChangesApplied( 90 ModelTypeFromInt(i), 91 0, ImmutableChangeRecordList(&local_changes)); 92 } 93 94 PumpLoop(); 95 } 96 97 TEST_F(JsMutationEventObserverTest, OnChangesComplete) { 98 InSequence dummy; 99 100 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 101 base::DictionaryValue expected_details; 102 expected_details.SetString( 103 "modelType", 104 ModelTypeToString(ModelTypeFromInt(i))); 105 EXPECT_CALL(mock_js_event_handler_, 106 HandleJsEvent("onChangesComplete", 107 HasDetailsAsDictionary(expected_details))); 108 } 109 110 for (int i = FIRST_REAL_MODEL_TYPE; i < MODEL_TYPE_COUNT; ++i) { 111 js_mutation_event_observer_.OnChangesComplete( 112 ModelTypeFromInt(i)); 113 } 114 PumpLoop(); 115 } 116 117 } // namespace 118 } // namespace syncer 119