Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / apps / app_shim_menu_controller_mac_browsertest.mm
1 // Copyright 2013 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 "chrome/browser/ui/cocoa/apps/app_shim_menu_controller_mac.h"
6
7 #import <Cocoa/Cocoa.h>
8
9 #include "base/command_line.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "base/strings/sys_string_conversions.h"
12 #include "chrome/browser/apps/app_browsertest_util.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser_iterator.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "extensions/browser/app_window/app_window_registry.h"
19 #include "extensions/browser/app_window/native_app_window.h"
20 #include "extensions/browser/uninstall_reason.h"
21 #include "extensions/common/extension.h"
22 #include "extensions/test/extension_test_message_listener.h"
23
24 namespace {
25
26 class AppShimMenuControllerBrowserTest
27     : public extensions::PlatformAppBrowserTest {
28  protected:
29   AppShimMenuControllerBrowserTest()
30       : app_1_(NULL),
31         app_2_(NULL),
32         initial_menu_item_count_(0) {}
33
34   virtual ~AppShimMenuControllerBrowserTest() {}
35
36   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
37     PlatformAppBrowserTest::SetUpCommandLine(command_line);
38   }
39
40   // Start two apps and wait for them to be launched.
41   void SetUpApps() {
42     ExtensionTestMessageListener listener_1("Launched", false);
43     app_1_ = InstallAndLaunchPlatformApp("minimal_id");
44     ASSERT_TRUE(listener_1.WaitUntilSatisfied());
45     ExtensionTestMessageListener listener_2("Launched", false);
46     app_2_ = InstallAndLaunchPlatformApp("minimal");
47     ASSERT_TRUE(listener_2.WaitUntilSatisfied());
48
49     initial_menu_item_count_ = [[[NSApp mainMenu] itemArray] count];
50   }
51
52   void CheckHasAppMenus(const extensions::Extension* app) const {
53     const int kExtraTopLevelItems = 4;
54     NSArray* item_array = [[NSApp mainMenu] itemArray];
55     EXPECT_EQ(initial_menu_item_count_ + kExtraTopLevelItems,
56               [item_array count]);
57     for (NSUInteger i = 0; i < initial_menu_item_count_; ++i)
58       EXPECT_TRUE([[item_array objectAtIndex:i] isHidden]);
59     NSMenuItem* app_menu = [item_array objectAtIndex:initial_menu_item_count_];
60     EXPECT_EQ(app->id(), base::SysNSStringToUTF8([app_menu title]));
61     EXPECT_EQ(app->name(),
62               base::SysNSStringToUTF8([[app_menu submenu] title]));
63     for (NSUInteger i = initial_menu_item_count_;
64          i < initial_menu_item_count_ + kExtraTopLevelItems;
65          ++i) {
66       NSMenuItem* menu = [item_array objectAtIndex:i];
67       EXPECT_GT([[menu submenu] numberOfItems], 0);
68       EXPECT_FALSE([menu isHidden]);
69     }
70   }
71
72   void CheckNoAppMenus() const {
73     NSArray* item_array = [[NSApp mainMenu] itemArray];
74     EXPECT_EQ(initial_menu_item_count_, [item_array count]);
75     for (NSUInteger i = 0; i < initial_menu_item_count_; ++i)
76       EXPECT_FALSE([[item_array objectAtIndex:i] isHidden]);
77   }
78
79   const extensions::Extension* app_1_;
80   const extensions::Extension* app_2_;
81   NSUInteger initial_menu_item_count_;
82
83  private:
84   DISALLOW_COPY_AND_ASSIGN(AppShimMenuControllerBrowserTest);
85 };
86
87 // Test that focusing an app window changes the menu bar.
88 IN_PROC_BROWSER_TEST_F(AppShimMenuControllerBrowserTest,
89                        PlatformAppFocusUpdatesMenuBar) {
90   SetUpApps();
91   // When an app is focused, all Chrome menu items should be hidden, and a menu
92   // item for the app should be added.
93   extensions::AppWindow* app_1_app_window =
94       extensions::AppWindowRegistry::Get(profile())
95           ->GetAppWindowsForApp(app_1_->id()).front();
96   [[NSNotificationCenter defaultCenter]
97       postNotificationName:NSWindowDidBecomeMainNotification
98                     object:app_1_app_window->GetNativeWindow()];
99   CheckHasAppMenus(app_1_);
100
101   // When another app is focused, the menu item for the app should change.
102   extensions::AppWindow* app_2_app_window =
103       extensions::AppWindowRegistry::Get(profile())
104           ->GetAppWindowsForApp(app_2_->id()).front();
105   [[NSNotificationCenter defaultCenter]
106       postNotificationName:NSWindowDidBecomeMainNotification
107                     object:app_2_app_window->GetNativeWindow()];
108   CheckHasAppMenus(app_2_);
109
110   // When a browser window is focused, the menu items for the app should be
111   // removed.
112   BrowserWindow* chrome_window = chrome::BrowserIterator()->window();
113   [[NSNotificationCenter defaultCenter]
114       postNotificationName:NSWindowDidBecomeMainNotification
115                     object:chrome_window->GetNativeWindow()];
116   CheckNoAppMenus();
117
118   // When an app window is closed and there are no other app windows, the menu
119   // items for the app should be removed.
120   app_1_app_window->GetBaseWindow()->Close();
121   chrome_window->Close();
122   [[NSNotificationCenter defaultCenter]
123       postNotificationName:NSWindowWillCloseNotification
124                     object:app_2_app_window->GetNativeWindow()];
125   CheckNoAppMenus();
126 }
127
128 IN_PROC_BROWSER_TEST_F(AppShimMenuControllerBrowserTest,
129                        ExtensionUninstallUpdatesMenuBar) {
130   SetUpApps();
131
132   // This essentially tests that a NSWindowWillCloseNotification gets fired when
133   // an app is uninstalled. We need to close the other windows first since the
134   // menu only changes on a NSWindowWillCloseNotification if there are no other
135   // windows.
136   extensions::AppWindow* app_2_app_window =
137       extensions::AppWindowRegistry::Get(profile())
138           ->GetAppWindowsForApp(app_2_->id()).front();
139   app_2_app_window->GetBaseWindow()->Close();
140
141   chrome::BrowserIterator()->window()->Close();
142
143   extensions::AppWindow* app_1_app_window =
144       extensions::AppWindowRegistry::Get(profile())
145           ->GetAppWindowsForApp(app_1_->id()).front();
146   [[NSNotificationCenter defaultCenter]
147       postNotificationName:NSWindowDidBecomeMainNotification
148                     object:app_1_app_window->GetNativeWindow()];
149
150   CheckHasAppMenus(app_1_);
151   ExtensionService::UninstallExtensionHelper(
152       extension_service(),
153       app_1_->id(),
154       extensions::UNINSTALL_REASON_FOR_TESTING);
155   CheckNoAppMenus();
156 }
157
158 }  // namespace