1# Copyright 2015 The Chromium OS 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
5import logging
6import utils
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.cros import enterprise_policy_base
10
11
12class policy_PopupsBlockedForUrls(enterprise_policy_base.EnterprisePolicyTest):
13    """Test PopupsBlockedForUrls policy effect on CrOS look & feel.
14
15    This test verifies the behavior of Chrome OS with a range of valid values
16    for the PopupsBlockedForUrls user policy, when DefaultPopupsSetting=1
17    (i.e., allow popups by default on all pages except those in domains listed
18    in PopupsBlockedForUrls). These valid values are covered by 4 test cases,
19    named: NotSet_Allowed, 1Url_Blocked, 2Urls_Allowed, and 3Urls_Blocked.
20
21    When the policy value is None (as in case NotSet_Allowed), then popups are
22    allowed on any page. When the value is set to one or more URLs (as in
23    1Url_Blocked, 2Urls_Allowed, and 3Urls_Blocked), popups are blocked only
24    on pages with a domain that matches any of the listed URLs, and allowed on
25    any of those that do not match.
26
27    As noted above, this test requires the DefaultPopupsSetting policy to be
28    set to 1. A related test, policy_PopupsAllowedForUrls, requires the value
29    to be set to 2. That value blocks popups on all pages except those with
30    domains listed in PopupsAllowedForUrls.
31
32    """
33    version = 1
34
35    POLICY_NAME = 'PopupsBlockedForUrls'
36    URL_HOST = 'http://localhost'
37    URL_PORT = 8080
38    URL_BASE = '%s:%d' % (URL_HOST, URL_PORT)
39    URL_PAGE = '/popup_status.html'
40    TEST_URL = URL_BASE + URL_PAGE
41
42    URL1_DATA = [URL_HOST]
43    URL2_DATA = ['http://www.bing.com', 'https://www.yahoo.com']
44    URL3_DATA = ['http://www.bing.com', URL_BASE,
45                 'https://www.yahoo.com']
46    TEST_CASES = {
47        'NotSet_Allowed': '',
48        '1Url_Blocked': URL1_DATA,
49        '2Urls_Allowed': URL2_DATA,
50        '3Urls_Blocked': URL3_DATA
51    }
52    STARTUP_URLS = ['chrome://policy', 'chrome://settings']
53    SUPPORTING_POLICIES = {
54        'DefaultPopupsSetting': 1,
55        'BookmarkBarEnabled': False,
56        'RestoreOnStartupURLs': STARTUP_URLS,
57        'RestoreOnStartup': 4
58    }
59
60    def initialize(self, args=()):
61        super(policy_PopupsBlockedForUrls, self).initialize(args)
62        self.start_webserver(self.URL_PORT)
63
64    def cleanup(self):
65        if self._web_server:
66            self._web_server.stop()
67        super(policy_PopupsBlockedForUrls, self).cleanup()
68
69    def _wait_for_page_ready(self, tab):
70        utils.poll_for_condition(
71            lambda: tab.EvaluateJavaScript('pageReady'),
72            exception=error.TestError('Test page is not ready.'))
73
74    def _test_popups_blocked_for_urls(self, policy_value, policies_json):
75        """Verify CrOS enforces the PopupsBlockedForUrls policy.
76
77        When PopupsBlockedForUrls is undefined, popups shall be allowed on
78        all pages. When PopupsBlockedForUrls contains one or more URLs, popups
79        shall be blocked only on the pages whose domain matches any of the
80        listed URLs.
81
82        @param policy_value: policy value expected on chrome://policy page.
83        @param policies_json: policy JSON data to send to the fake DM server.
84
85        """
86        self.setup_case(self.POLICY_NAME, policy_value, policies_json)
87        logging.info('Running _test_popups_blocked_for_urls(%s, %s)',
88                     policy_value, policies_json)
89
90        tab = self.navigate_to_url(self.TEST_URL)
91        self._wait_for_page_ready(tab)
92        is_blocked = tab.EvaluateJavaScript('isPopupBlocked();')
93
94        # String |URL_HOST| will be found in string |policy_value| for
95        # test cases 1Url_Blocked and 3Urls_Blocked, but not for cases
96        # NotSet_Allowed and 2Urls_Allowed.
97        if policy_value is not None and self.URL_HOST in policy_value:
98            if not is_blocked:
99                raise error.TestFail('Popups should be blocked.')
100        else:
101            if is_blocked:
102                raise error.TestFail('Popups should not be blocked.')
103        tab.Close()
104
105    def _run_test_case(self, case):
106        """Setup and run the test configured for the specified test case.
107
108        Set the expected |policy_value| and |policies_json| data based on the
109        test |case|. If the user specified an expected |value| in the command
110        line args, then use it to set the |policy_value| and blank out the
111        |policies_json|.
112
113        @param case: Name of the test case to run.
114
115        """
116        if self.is_value_given:
117            # If |value| was given in args, then set expected |policy_value|
118            # to the given value, and setup |policies_json| data to None.
119            policy_value = self.value
120            policies_json = None
121        else:
122            # Otherwise, set expected |policy_value| and setup |policies_json|
123            # data to the values specified by the test |case|.
124            policy_value = ','.join(self.TEST_CASES[case])
125            policy_json = {self.POLICY_NAME: self.TEST_CASES[case]}
126            policies_json = self.SUPPORTING_POLICIES.copy()
127            policies_json.update(policy_json)
128
129        # Run test using the values configured for the test case.
130        self._test_popups_blocked_for_urls(policy_value, policies_json)
131
132    def run_once(self):
133        # The run_once() method is required by autotest. We call the base
134        # class run_once_impl() method, which handles command-line run modes,
135        # and pass in the standard _run_test_case() method of this test.
136        self.run_once_impl(self._run_test_case)
137