- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / mac / keystone_glue_unittest.mm
1 // Copyright (c) 2011 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 #import <Foundation/Foundation.h>
6 #import <objc/objc-class.h>
7
8 #import "chrome/browser/mac/keystone_glue.h"
9 #import "chrome/browser/mac/keystone_registration.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "testing/platform_test.h"
12
13 namespace ksr = keystone_registration;
14
15
16 @interface FakeKeystoneRegistration : KSRegistration
17 @end
18
19
20 // This unit test implements FakeKeystoneRegistration as a KSRegistration
21 // subclass. It won't be linked against KSRegistration, so provide a stub
22 // KSRegistration class on which to base FakeKeystoneRegistration.
23 @implementation KSRegistration
24
25 + (id)registrationWithProductID:(NSString*)productID {
26   return nil;
27 }
28
29 - (BOOL)registerWithParameters:(NSDictionary*)args {
30   return NO;
31 }
32
33 - (BOOL)promoteWithParameters:(NSDictionary*)args
34                 authorization:(AuthorizationRef)authorization {
35   return NO;
36 }
37
38 - (void)setActive {
39 }
40
41 - (void)checkForUpdate {
42 }
43
44 - (void)startUpdate {
45 }
46
47 - (ksr::KSRegistrationTicketType)ticketType {
48   return ksr::kKSRegistrationDontKnowWhatKindOfTicket;
49 }
50
51 @end
52
53
54 @implementation FakeKeystoneRegistration
55
56 // Send the notifications that a real KeystoneGlue object would send.
57
58 - (void)checkForUpdate {
59   NSNumber* yesNumber = [NSNumber numberWithBool:YES];
60   NSString* statusKey = @"Status";
61   NSDictionary* dictionary = [NSDictionary dictionaryWithObject:yesNumber
62                                                          forKey:statusKey];
63   NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
64   [center postNotificationName:ksr::KSRegistrationCheckForUpdateNotification
65                         object:nil
66                       userInfo:dictionary];
67 }
68
69 - (void)startUpdate {
70   NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
71   [center postNotificationName:ksr::KSRegistrationStartUpdateNotification
72                         object:nil];
73 }
74
75 @end
76
77
78 @interface FakeKeystoneGlue : KeystoneGlue {
79  @public
80   BOOL upToDate_;
81   NSString *latestVersion_;
82   BOOL successful_;
83   int installs_;
84 }
85
86 - (void)fakeAboutWindowCallback:(NSNotification*)notification;
87 @end
88
89
90 @implementation FakeKeystoneGlue
91
92 - (id)init {
93   if ((self = [super init])) {
94     // some lies
95     upToDate_ = YES;
96     latestVersion_ = @"foo bar";
97     successful_ = YES;
98     installs_ = 1010101010;
99
100     // Set up an observer that takes the notification that the About window
101     // listens for.
102     NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
103     [center addObserver:self
104                selector:@selector(fakeAboutWindowCallback:)
105                    name:kAutoupdateStatusNotification
106                  object:nil];
107   }
108   return self;
109 }
110
111 - (void)dealloc {
112   [[NSNotificationCenter defaultCenter] removeObserver:self];
113   [super dealloc];
114 }
115
116 // For mocking
117 - (NSDictionary*)infoDictionary {
118   NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
119                                      @"http://foo.bar", @"KSUpdateURL",
120                                      @"com.google.whatever", @"KSProductID",
121                                      @"0.0.0.1", @"KSVersion",
122                                      nil];
123   return dict;
124 }
125
126 // For mocking
127 - (BOOL)loadKeystoneRegistration {
128   return YES;
129 }
130
131 // Confirms certain things are happy
132 - (BOOL)dictReadCorrectly {
133   return ([url_ isEqual:@"http://foo.bar"] &&
134           [productID_ isEqual:@"com.google.whatever"] &&
135           [version_ isEqual:@"0.0.0.1"]);
136 }
137
138 // Confirms certain things are happy
139 - (BOOL)hasATimer {
140   return timer_ ? YES : NO;
141 }
142
143 - (void)addFakeRegistration {
144   registration_ = [[FakeKeystoneRegistration alloc] init];
145 }
146
147 - (void)fakeAboutWindowCallback:(NSNotification*)notification {
148   NSDictionary* dictionary = [notification userInfo];
149   AutoupdateStatus status = static_cast<AutoupdateStatus>(
150       [[dictionary objectForKey:kAutoupdateStatusStatus] intValue]);
151
152   if (status == kAutoupdateAvailable) {
153     upToDate_ = NO;
154     latestVersion_ = [dictionary objectForKey:kAutoupdateStatusVersion];
155   } else if (status == kAutoupdateInstallFailed) {
156     successful_ = NO;
157     installs_ = 0;
158   }
159 }
160
161 // Confirm we look like callbacks with nil NSNotifications
162 - (BOOL)confirmCallbacks {
163   return (!upToDate_ &&
164           (latestVersion_ == nil) &&
165           !successful_ &&
166           (installs_ == 0));
167 }
168
169 @end
170
171
172 namespace {
173
174 class KeystoneGlueTest : public PlatformTest {
175 };
176
177 // DISABLED because the mocking isn't currently working.
178 TEST_F(KeystoneGlueTest, DISABLED_BasicGlobalCreate) {
179   // Allow creation of a KeystoneGlue by mocking out a few calls
180   SEL ids = @selector(infoDictionary);
181   IMP oldInfoImp_ = [[KeystoneGlue class] instanceMethodForSelector:ids];
182   IMP newInfoImp_ = [[FakeKeystoneGlue class] instanceMethodForSelector:ids];
183   Method infoMethod_ = class_getInstanceMethod([KeystoneGlue class], ids);
184   method_setImplementation(infoMethod_, newInfoImp_);
185
186   SEL lks = @selector(loadKeystoneRegistration);
187   IMP oldLoadImp_ = [[KeystoneGlue class] instanceMethodForSelector:lks];
188   IMP newLoadImp_ = [[FakeKeystoneGlue class] instanceMethodForSelector:lks];
189   Method loadMethod_ = class_getInstanceMethod([KeystoneGlue class], lks);
190   method_setImplementation(loadMethod_, newLoadImp_);
191
192   KeystoneGlue *glue = [KeystoneGlue defaultKeystoneGlue];
193   ASSERT_TRUE(glue);
194
195   // Fix back up the class to the way we found it.
196   method_setImplementation(infoMethod_, oldInfoImp_);
197   method_setImplementation(loadMethod_, oldLoadImp_);
198 }
199
200 // DISABLED because the mocking isn't currently working.
201 TEST_F(KeystoneGlueTest, DISABLED_BasicUse) {
202   FakeKeystoneGlue* glue = [[[FakeKeystoneGlue alloc] init] autorelease];
203   [glue loadParameters];
204   ASSERT_TRUE([glue dictReadCorrectly]);
205
206   // Likely returns NO in the unit test, but call it anyway to make
207   // sure it doesn't crash.
208   [glue loadKeystoneRegistration];
209
210   // Confirm we start up an active timer
211   [glue registerWithKeystone];
212   ASSERT_TRUE([glue hasATimer]);
213   [glue stopTimer];
214
215   // Brief exercise of callbacks
216   [glue addFakeRegistration];
217   [glue checkForUpdate];
218   [glue installUpdate];
219   ASSERT_TRUE([glue confirmCallbacks]);
220 }
221
222 }  // namespace