def test_bundle_defer_async_production(self):
        """The default and logged-in production bundles should never be loaded
        async or defered.
        For bundles to be loaded async or defered, you need to empty merge_with
        """
        registry = getUtility(IRegistry)

        bundles = registry.collectionOfInterface(
            IBundleRegistry,
            prefix="plone.bundles"
        )
        bundles['plone'].load_async = False
        bundles['plone'].load_defer = False
        bundles['plone-logged-in'].load_async = False
        bundles['plone-logged-in'].load_defer = False

        view = ScriptsView(self.app, self.app.REQUEST, None, None)

        import Products.CMFPlone.resources.browser
        path = os.path.dirname(Products.CMFPlone.resources.browser.__file__)
        view.index = ViewPageTemplateFile('scripts.pt', path)
        view.update()

        self.assertTrue('async="async"' not in view.index(view))
        self.assertTrue('defer="defer"' not in view.index(view))

        bundles['plone'].load_async = True
        bundles['plone'].load_defer = True
        self.assertEqual(view.index(view).count('async="async"'), 0)
        self.assertEqual(view.index(view).count('defer="defer"'), 0)

        bundles['plone'].merge_with = ''
        bundles['plone'].load_async = True
        bundles['plone'].load_defer = True
        self.assertEqual(view.index(view).count('async="async"'), 1)
        self.assertEqual(view.index(view).count('defer="defer"'), 1)

        bundles['plone'].merge_with = ''
        bundles['plone'].load_async = True
        bundles['plone'].load_defer = True
        bundles['plone-logged-in'].merge_with = ''
        bundles['plone-logged-in'].load_async = True
        bundles['plone-logged-in'].load_defer = True
        self.assertEqual(view.index(view).count('async="async"'), 2)
        self.assertEqual(view.index(view).count('defer="defer"'), 2)
    def test_bundle_defer_async(self):
        registry = getUtility(IRegistry)

        bundles = registry.collectionOfInterface(
            IBundleRegistry,
            prefix="plone.bundles"
        )
        bundle = bundles.add('foobar')
        bundle.name = 'foobar'
        bundle.jscompilation = 'foobar.js'
        bundle.csscompilation = 'foobar.css'
        bundle.resources = ['foobar']

        view = ScriptsView(self.app, self.app.REQUEST, None, None)
        view.get_cooked_bundles = lambda: [('foobar', bundle)]

        import Products.CMFPlone.resources.browser
        path = os.path.dirname(Products.CMFPlone.resources.browser.__file__)
        view.index = ViewPageTemplateFile('scripts.pt', path)
        view.update()

        self.assertTrue('async="async"' not in view.index(view))
        self.assertTrue('defer="defer"' not in view.index(view))

        bundle.load_async = True
        bundle.load_defer = False
        self.assertTrue('async="async"' in view.index(view))
        self.assertTrue('defer="defer"' not in view.index(view))

        bundle.load_async = False
        bundle.load_defer = True
        self.assertTrue('async="async"' not in view.index(view))
        self.assertTrue('defer="defer"' in view.index(view))

        bundle.load_async = True
        bundle.load_defer = True

        self.assertTrue('async="async"' in view.index(view))
        self.assertTrue('defer="defer"' in view.index(view))

        bundle.load_async = False
        bundle.load_defer = False

        self.assertTrue('async="async"' not in view.index(view))
        self.assertTrue('defer="defer"' not in view.index(view))