#!/usr/bin/python3

# checkpoint:
# 1. create blueprint
# 2. blueprint filter
# 3. blueprint sort

import composerlib
import testlib


@testlib.nondestructive
class TestBlueprint(composerlib.ComposerCase):

    def testCreate(self):
        b = self.browser

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        # create blueprint
        b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
        b.wait_visible("div[role=dialog] #cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", "")
        b.set_input_text("#textInput2-modal-markup", "test")
        # should have error message and disable Create button
        b.wait_text("#cmpsr-modal-crt-blueprint .help-block", "A blueprint name is required.")
        b.wait_attr("#create-blueprint-modal-create-button", "disabled", "")
        b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
        b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")

        # invalid characters for blueprint name
        invalid_chars = {
            " ": "spaces.",
            "$": "the character: $",
            "/*": "the characters: / *",
            "= ": "spaces or the character: =",
            " ! '": "spaces or the characters: ! '"
        }
        for c in invalid_chars.keys():
            b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
            b.wait_visible("div[role=dialog] #cmpsr-modal-crt-blueprint")
            # empty name blueprint
            b.set_input_text("#textInput-modal-markup", "-_.{}".format(c))
            b.wait_text("#cmpsr-modal-crt-blueprint .help-block",
                        "Blueprint names cannot contain {}".format(invalid_chars[c]))
        b.click("#cmpsr-modal-crt-blueprint .modal-header .close")
        b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")

        # duplicate name
        # wait until the openssh-server blueprint is there
        b.wait_in_text("ul[aria-label=Blueprints]", "openssh-server")
        b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
        b.wait_visible("div[role=dialog] #cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", "openssh-server")
        b.set_input_text("#textInput2-modal-markup", "openssh server image")
        b.wait_text("#cmpsr-modal-crt-blueprint .help-block",
                    "The name openssh-server already exists.")
        b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
        b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")

        # duplicate name (by pressing enter)
        # wait until the openssh-server blueprint is there
        b.wait_in_text("ul[aria-label=Blueprints]", "openssh-server")
        b.click(".toolbar-pf-action-right #cmpsr-btn-crt-blueprint")
        b.wait_visible("div[role=dialog] #cmpsr-modal-crt-blueprint")
        # empty name blueprint
        b.set_input_text("#textInput-modal-markup", "openssh-server", blur=False)
        b.key_press("\r")
        b.wait_text("#cmpsr-modal-crt-blueprint .alert-danger", "Specify a new blueprint name.")
        b.click("#cmpsr-modal-crt-blueprint button:contains('Cancel')")
        b.wait_not_present("div[role=dialog] #cmpsr-modal-crt-blueprint")

        # collect code coverage result
        self.check_coverage()

    def testFilter(self):
        b = self.browser

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        # filter "openssh-server" blueprint
        b.set_input_text("#filter-blueprints", "openssh", blur=False)
        b.key_press("\r")
        b.wait_in_text(".filter-pf-active-label + .list-inline .label", "Name: openssh")
        b.wait_visible("#openssh-server-name")
        b.wait_not_present("#httpd-server-name")
        # clear filter
        b.click(".filter-pf-active-label + .list-inline .pficon-close")
        b.wait_not_present("p:contains('Active filters:')")

        # filter "httpd" will show three matched blueprints
        b.set_input_text("#filter-blueprints", "httpd", blur=False)
        b.key_press("\r")
        b.wait_in_text(".filter-pf-active-label + .list-inline .label", "Name: httpd")
        b.wait_not_present("#openssh-server-name")
        b.wait_visible("#httpd-server-name")
        b.wait_visible("#httpd-server-with-hostname-name")
        b.wait_visible("#httpd-server-with-user-name")
        # clear filter
        b.click("button:contains('Clear all filters')")
        b.wait_not_present("p:contains('Active filters:')")

        # collect code coverage result
        self.check_coverage()

    def testSort(self):
        b = self.browser

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        blueprint_list = [
            "httpd-server",
            "httpd-server-with-hostname",
            "httpd-server-with-user",
            "openssh-server"
        ]
        # sort from Z-A
        b.wait_visible("ul[aria-label=Blueprints]")
        b.click(".fa-sort-alpha-asc")
        b.wait_visible(".fa-sort-alpha-desc")
        for i, v in enumerate(sorted(blueprint_list, reverse=True)):
            b.wait_text("ul[aria-label=Blueprints] li:nth-child({}) a strong".format(i + 1), v)

        # sort from A-Z
        b.click(".fa-sort-alpha-desc")
        b.wait_visible(".fa-sort-alpha-asc")
        for i, v in enumerate(sorted(blueprint_list)):
            b.wait_text("ul[aria-label=Blueprints] li:nth-child({}) a strong".format(i + 1), v)

        # collect code coverage result
        self.check_coverage()

    def testExport(self):
        b = self.browser

        self.login_and_go("/composer", superuser=True)
        b.wait_visible("#main")

        # export package list
        actions_drop_down_sel = "#openssh-server-kebab"
        b.click(actions_drop_down_sel)
        b.wait_attr(actions_drop_down_sel, "aria-expanded", "true")
        b.click("li[data-blueprint=openssh-server] a:contains('Export')")
        b.wait_visible("#cmpsr-modal-export")
        with b.wait_timeout(300):
            b.wait_in_text("#textInput2-modal-markup", "openssh-server")
        b.click("#cmpsr-modal-export button[data-btn=copy-export]")
        b.click("#cmpsr-modal-export button[data-btn=close-export]")
        b.wait_not_present("#cmpsr-modal-export")

        # collect code coverage result
        self.check_coverage()


if __name__ == '__main__':
    testlib.test_main()
