From 0c14869ad791cdacb2d40296ee179944affda8ae Mon Sep 17 00:00:00 2001 From: Bill Smith Date: Mon, 28 Oct 2019 23:20:15 -0700 Subject: [PATCH 1/9] SHIBUI-1503 Added tests for delegated admin functionality. --- .../admin/ui/SeleniumSIDETest.groovy | 3 + .../integration/resources/SHIBUI-1503-1.side | 504 ++++++++++++++++++ .../integration/resources/SHIBUI-1503-2.side | 200 +++++++ .../integration/resources/SHIBUI-1503-3.side | 192 +++++++ 4 files changed, 899 insertions(+) create mode 100644 backend/src/integration/resources/SHIBUI-1503-1.side create mode 100644 backend/src/integration/resources/SHIBUI-1503-2.side create mode 100644 backend/src/integration/resources/SHIBUI-1503-3.side diff --git a/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy b/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy index e68d43739..75167259a 100644 --- a/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy +++ b/backend/src/integration/groovy/edu/internet2/tier/shibboleth/admin/ui/SeleniumSIDETest.groovy @@ -124,6 +124,9 @@ class SeleniumSIDETest extends Specification { 'SHIBUI-1391: Regex Validation' | '/SHIBUI-1391.side' 'SHIBUI-1407: Metadata source comparison highlights' | '/SHIBUI-1407-1.side' 'SHIBUI-1407: Metadata provider comparison highlights' | '/SHIBUI-1407-2.side' + 'SHIBUI-1503: Non-admin can create metadata source' | '/SHIBUI-1503-1.side' + 'SHIBUI-1503: User can be deleted' | '/SHIBUI-1503-2.side' + 'SHIBUI-1503: User can be enabled' | '/SHIBUI-1503-3.side' } } diff --git a/backend/src/integration/resources/SHIBUI-1503-1.side b/backend/src/integration/resources/SHIBUI-1503-1.side new file mode 100644 index 000000000..844ce69fd --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-1503-1.side @@ -0,0 +1,504 @@ +{ + "id": "2b5fc163-381b-4237-8abb-a2f5aaf2a5b7", + "version": "2.0", + "name": "SHIBUI-1503-1", + "url": "http://localhost:10101", + "tests": [{ + "id": "3f0e6ded-0b61-4d71-9f74-937cbd972cb3", + "name": "SHIBUI-1503-1", + "commands": [{ + "id": "86ad3094-9850-478e-9020-e5c894ea17a7", + "comment": "", + "command": "open", + "target": "/login", + "targets": [], + "value": "" + }, { + "id": "b39e96ee-c5a0-4e85-b86b-b41ce815fcde", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "nonadmin" + }, { + "id": "b0d833bc-eda8-4e7a-9ba7-f002394340f7", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "nonadminpass" + }, { + "id": "ca7d0095-749c-4709-80aa-0083dc477d20", + "comment": "", + "command": "click", + "target": "name=submit", + "targets": [ + ["name=submit", "name"], + ["css=td:nth-child(1) > input", "css:finder"], + ["xpath=//input[@name='submit']", "xpath:attributes"], + ["xpath=//tr[3]/td/input", "xpath:position"] + ], + "value": "" + }, { + "id": "db912e0e-b9c9-4693-92cf-a43a9756d253", + "comment": "", + "command": "waitForElementVisible", + "target": "css=#addNewDropdown > translate-i18n", + "targets": [], + "value": "30000" + }, { + "id": "fcb0a214-ead2-407e-b2b2-ddac954e1348", + "comment": "", + "command": "click", + "target": "css=#addNewDropdown > translate-i18n", + "targets": [ + ["css=#addNewDropdown > translate-i18n", "css:finder"], + ["xpath=//button[@id='addNewDropdown']/translate-i18n", "xpath:idRelative"], + ["xpath=//translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Add New')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "837ce33c-8787-4b31-9f8c-d250e5fae525", + "comment": "", + "command": "click", + "target": "linkText=Metadata Source", + "targets": [ + ["linkText=Metadata Source", "linkText"], + ["css=.dropdown-menu > .nav-link:nth-child(1)", "css:finder"], + ["xpath=//div[@id='navbar']/ul/li/div/a", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '')])[2]", "xpath:href"], + ["xpath=//div/a", "xpath:position"] + ], + "value": "" + }, { + "id": "38afb51c-c3ae-47ca-8d1f-02f26ba2440f", + "comment": "", + "command": "waitForElementEditable", + "target": "id=/serviceProviderName", + "targets": [], + "value": "30000" + }, { + "id": "aa956591-ae81-4637-8d89-b6c45daccf86", + "comment": "", + "command": "type", + "target": "id=/serviceProviderName", + "targets": [ + ["id=/serviceProviderName", "id"], + ["name=field1", "name"], + ["css=#\\/serviceProviderName", "css:finder"], + ["xpath=//input[@id='/serviceProviderName']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "Test Source" + }, { + "id": "ff0ff7cf-ab9b-4dcf-bc9a-ffc005632363", + "comment": "", + "command": "type", + "target": "id=/entityId", + "targets": [ + ["id=/entityId", "id"], + ["name=field2", "name"], + ["css=#\\/entityId", "css:finder"], + ["xpath=//input[@id='/entityId']", "xpath:attributes"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/custom-string/div/input", "xpath:position"] + ], + "value": "test" + }, { + "id": "d1726c2a-6b56-427b-9a3d-722e64c45bd9", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[2]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "9fb1da6c-d002-4e8d-a9af-c809de9cbc58", + "comment": "", + "command": "waitForElementEditable", + "target": "id=/organization/name", + "targets": [], + "value": "30000" + }, { + "id": "68288af1-2686-49b5-b1b9-10f68046fc0a", + "comment": "", + "command": "type", + "target": "id=/organization/name", + "targets": [ + ["id=/organization/name", "id"], + ["name=field5", "name"], + ["css=#\\/organization\\/name", "css:finder"], + ["xpath=//input[@id='/organization/name']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "Org Name" + }, { + "id": "c785c85c-1515-4bd0-8886-576f568a2efc", + "comment": "", + "command": "type", + "target": "id=/organization/displayName", + "targets": [ + ["id=/organization/displayName", "id"], + ["name=field6", "name"], + ["css=#\\/organization\\/displayName", "css:finder"], + ["xpath=//input[@id='/organization/displayName']", "xpath:attributes"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/custom-string/div/input", "xpath:position"] + ], + "value": "Org Display Name" + }, { + "id": "2cacc9c6-8a1a-4923-aa8d-00dea1172dd0", + "comment": "", + "command": "type", + "target": "id=/organization/url", + "targets": [ + ["id=/organization/url", "id"], + ["name=field7", "name"], + ["css=#\\/organization\\/url", "css:finder"], + ["xpath=//input[@id='/organization/url']", "xpath:attributes"], + ["xpath=//div[3]/sf-form-element/div/sf-widget-chooser/custom-string/div/input", "xpath:position"] + ], + "value": "Org URL" + }, { + "id": "8441a497-6a79-4396-af40-6f7ce8056cfe", + "comment": "", + "command": "click", + "target": "css=.btn-success", + "targets": [ + ["css=.btn-success", "css:finder"], + ["xpath=//div/button", "xpath:position"], + ["xpath=//button[contains(.,'Add   ')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "383707e1-ae7d-44c5-a91a-69a1f3bc601e", + "comment": "", + "command": "click", + "target": "css=.label:nth-child(1)", + "targets": [ + ["css=.label:nth-child(1)", "css:finder"], + ["xpath=//li[3]/button/span", "xpath:position"] + ], + "value": "" + }, { + "id": "57d66e91-4e76-410b-8ecc-c5c8f2459606", + "comment": "", + "command": "click", + "target": "css=.label:nth-child(1)", + "targets": [ + ["css=.label:nth-child(1)", "css:finder"], + ["xpath=//li[3]/button/span", "xpath:position"] + ], + "value": "" + }, { + "id": "8fc68685-f349-48f2-9929-6b99eb860823", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "7075f663-403e-44fc-bb34-17ecb2fee62a", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "ef48faaa-1077-4969-bc63-13049ff2cbf3", + "comment": "", + "command": "click", + "target": "css=.label:nth-child(1)", + "targets": [ + ["css=.label:nth-child(1)", "css:finder"], + ["xpath=//li[3]/button/span", "xpath:position"] + ], + "value": "" + }, { + "id": "1c5c0174-1181-479b-a8fa-00c759799d61", + "comment": "", + "command": "click", + "target": "css=.label:nth-child(1)", + "targets": [ + ["css=.label:nth-child(1)", "css:finder"], + ["xpath=//li[3]/button/span", "xpath:position"] + ], + "value": "" + }, { + "id": "16c0c8d5-ead6-4600-ad02-08963d73ae0b", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "8be428b3-5959-4598-a982-6708e6d39a85", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "32ecd0e3-b7a9-4978-923c-9992fba8f557", + "comment": "", + "command": "click", + "target": "css=.save", + "targets": [ + ["css=.save", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "a4131b2a-ab46-4dc6-827e-6ffa516c5bd8", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "e9a8182c-47d9-444c-8386-f84e1a7da38a", + "comment": "", + "command": "click", + "target": "css=li:nth-child(3) > .nav-link > translate-i18n", + "targets": [ + ["css=li:nth-child(3) > .nav-link > translate-i18n", "css:finder"], + ["xpath=//div[@id='navbar']/ul/li[3]/a/translate-i18n", "xpath:idRelative"], + ["xpath=//li[3]/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Logout')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "947a1fb8-a4b8-4ff0-997f-911741d60fc1", + "comment": "", + "command": "waitForElementEditable", + "target": "name=username", + "targets": [], + "value": "30000" + }, { + "id": "415f0118-6bff-4d5b-b964-a1a724b818e4", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "admin" + }, { + "id": "7e4a4734-c520-46d4-b214-b6e3e4c5618a", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "adminpass" + }, { + "id": "aa359f0d-e222-415c-81fc-409f387c2a35", + "comment": "", + "command": "click", + "target": "name=submit", + "targets": [ + ["name=submit", "name"], + ["css=td:nth-child(1) > input", "css:finder"], + ["xpath=//input[@name='submit']", "xpath:attributes"], + ["xpath=//tr[3]/td/input", "xpath:position"] + ], + "value": "" + }, { + "id": "990aff50-4646-4258-a9f0-ef5f39b8dc83", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.badge-pill", + "targets": [], + "value": "30000" + }, { + "id": "d77d51d9-fbf7-4358-a995-41fcf0f6885f", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "9fd2f2ad-6315-48be-b1e5-b958956c20be", + "comment": "", + "command": "assertText", + "target": "css=.badge-pill", + "targets": [ + ["css=.badge-pill", "css:finder"], + ["xpath=//li[4]/a/span", "xpath:position"], + ["xpath=//span[contains(.,'2')]", "xpath:innerText"] + ], + "value": "2" + }, { + "id": "9be511e0-ed11-4707-8490-6fa248e4138e", + "comment": "", + "command": "assertText", + "target": "css=.badge > span", + "targets": [ + ["css=.badge > span", "css:finder"], + ["xpath=//span/span", "xpath:position"] + ], + "value": "Disabled" + }, { + "id": "157e70d6-fa1c-4118-bce4-ab52000b6c16", + "comment": "", + "command": "click", + "target": "css=.nav-link > translate-i18n:nth-child(1)", + "targets": [ + ["css=.nav-link > translate-i18n:nth-child(1)", "css:finder"], + ["xpath=//li[4]/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Action Required')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b1a8c4b1-d164-4f32-adb3-6cfb76951f28", + "comment": "", + "command": "waitForElementVisible", + "target": "linkText=Test Source", + "targets": [], + "value": "30000" + }, { + "id": "ef70ab28-afe2-473d-aedb-d1d3bf04a538", + "comment": "", + "command": "assertText", + "target": "linkText=Test Source", + "targets": [ + ["linkText=Test Source", "linkText"], + ["css=td > a", "css:finder"], + ["xpath=//a[contains(text(),'Test Source')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/resolver/a56f0f83-cfc4-4f33-ae9a-5b786b815111/configuration/options')]", "xpath:href"], + ["xpath=//td/a", "xpath:position"], + ["xpath=//a[contains(.,'Test Source')]", "xpath:innerText"] + ], + "value": "Test Source" + }, { + "id": "708acbb6-63c7-4cb5-9c5a-f64c31ba6a40", + "comment": "", + "command": "assertText", + "target": "css=td:nth-child(2)", + "targets": [ + ["css=td:nth-child(2)", "css:finder"], + ["xpath=//td[2]", "xpath:position"], + ["xpath=//td[contains(.,'test')]", "xpath:innerText"] + ], + "value": "test" + }, { + "id": "6ba5a2fb-8c68-4743-99d6-1fa44644f399", + "comment": "", + "command": "assertText", + "target": "css=td:nth-child(3)", + "targets": [ + ["css=td:nth-child(3)", "css:finder"], + ["xpath=//td[3]", "xpath:position"], + ["xpath=//td[contains(.,'nonadmin')]", "xpath:innerText"] + ], + "value": "nonadmin" + }, { + "id": "eb63aa9f-4ac5-4852-8941-740b9f49a769", + "comment": "", + "command": "click", + "target": "css=.btn-success > translate-i18n", + "targets": [ + ["css=.btn-success > translate-i18n", "css:finder"], + ["xpath=//td[5]/button/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Enable')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8d064bfb-cf8f-428c-b436-2930f6295962", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "500d78cd-a2b4-49e6-8609-7d5f822942d0", + "comment": "", + "command": "assertText", + "target": "css=.badge", + "targets": [ + ["css=.badge", "css:finder"], + ["xpath=//li[4]/a/span", "xpath:position"], + ["xpath=//span[contains(.,'1')]", "xpath:innerText"] + ], + "value": "1" + }, { + "id": "3f92b1a1-9675-4da3-90d5-475a89a22913", + "comment": "", + "command": "click", + "target": "linkText=Metadata Sources", + "targets": [ + ["linkText=Metadata Sources", "linkText"], + ["css=.nav-item:nth-child(1) > .nav-link", "css:finder"], + ["xpath=//a[contains(text(),'Metadata Sources')]", "xpath:link"], + ["xpath=//a[contains(@href, '/dashboard/metadata/manager/resolvers')]", "xpath:href"], + ["xpath=//dashboard-page/div/ul/li/a", "xpath:position"], + ["xpath=//a[contains(.,'Metadata Sources')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "160d24df-7c98-469c-bfdb-6e39f0b44b0d", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "f76a12a3-2054-4be2-a6a6-2221afd493fb", + "comment": "", + "command": "assertText", + "target": "css=.badge > span", + "targets": [ + ["css=.badge > span", "css:finder"], + ["xpath=//span/span", "xpath:position"] + ], + "value": "Enabled" + }, { + "id": "6b4905b8-2ae3-4682-ae52-0149c58eb7f4", + "comment": "", + "command": "close", + "target": "", + "targets": [], + "value": "" + }] + }], + "suites": [{ + "id": "e0294618-9c01-4063-ba60-99fda5bb3edc", + "name": "Default Suite", + "persistSession": false, + "parallel": false, + "timeout": 300, + "tests": ["3f0e6ded-0b61-4d71-9f74-937cbd972cb3"] + }], + "urls": ["http://localhost:10101/"], + "plugins": [] +} \ No newline at end of file diff --git a/backend/src/integration/resources/SHIBUI-1503-2.side b/backend/src/integration/resources/SHIBUI-1503-2.side new file mode 100644 index 000000000..fbc65ae95 --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-1503-2.side @@ -0,0 +1,200 @@ +{ + "id": "5366ee48-b38e-45f0-a996-abe249f84e24", + "version": "2.0", + "name": "SHIBUI-1503-2", + "url": "http://localhost:10101", + "tests": [{ + "id": "3ee270a9-8a5c-4a17-92e7-ab9b013e7aee", + "name": "SHIBUI-1503-2", + "commands": [{ + "id": "b0d2001f-0afd-439b-833b-8c945404bb2a", + "comment": "", + "command": "open", + "target": "/login", + "targets": [], + "value": "" + }, { + "id": "c0e3c091-9a27-45f1-8525-dc6acb187ee1", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "admin" + }, { + "id": "96a54bfc-f203-43be-8d42-5bcdf7cfcdb7", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "adminpass" + }, { + "id": "624d4f0a-ddb6-4047-a25e-43cbde644fb5", + "comment": "", + "command": "click", + "target": "name=submit", + "targets": [ + ["name=submit", "name"], + ["css=td:nth-child(1) > input", "css:finder"], + ["xpath=//input[@name='submit']", "xpath:attributes"], + ["xpath=//tr[3]/td/input", "xpath:position"] + ], + "value": "" + }, { + "id": "812843b9-c71a-4141-b204-3387f0fee39a", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.nav-link > translate-i18n:nth-child(1)", + "targets": [], + "value": "30000" + }, { + "id": "473db033-9a76-4173-9a70-daa255f99b1d", + "comment": "", + "command": "click", + "target": "css=.nav-link > translate-i18n:nth-child(1)", + "targets": [ + ["css=.nav-link > translate-i18n:nth-child(1)", "css:finder"], + ["xpath=//li[4]/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Action Required')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a98143b5-647f-4e7e-b920-f6e6875d7372", + "comment": "", + "command": "click", + "target": "css=.fa-trash", + "targets": [ + ["css=.fa-trash", "css:finder"], + ["xpath=//div[2]/button/i", "xpath:position"] + ], + "value": "" + }, { + "id": "d85702e0-5eb2-4dd7-b10f-906352a43b49", + "comment": "", + "command": "click", + "target": "css=.modal-footer > .btn-danger", + "targets": [ + ["css=.modal-footer > .btn-danger", "css:finder"], + ["xpath=(//button[@type='button'])[2]", "xpath:attributes"], + ["xpath=//div[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "2d8da370-0a5a-4048-a8bd-f68210a271c5", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.text-center", + "targets": [], + "value": "30000" + }, { + "id": "d5a65352-5897-49cf-9046-3afc5397f193", + "comment": "", + "command": "assertText", + "target": "css=.text-center", + "targets": [ + ["css=.text-center", "css:finder"], + ["xpath=//p", "xpath:position"], + ["xpath=//p[contains(.,'There are no new user requests at this time.')]", "xpath:innerText"] + ], + "value": "There are no new user requests at this time." + }, { + "id": "ede68bbe-2236-457d-93d7-9e7cde5d5176", + "comment": "", + "command": "click", + "target": "css=li:nth-child(3) > .nav-link > translate-i18n", + "targets": [ + ["css=li:nth-child(3) > .nav-link > translate-i18n", "css:finder"], + ["xpath=//div[@id='navbar']/ul/li[3]/a/translate-i18n", "xpath:idRelative"], + ["xpath=//li[3]/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Logout')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "64b41d03-23dc-46cd-9612-9ad6ce86a169", + "comment": "", + "command": "waitForElementEditable", + "target": "name=username", + "targets": [], + "value": "30000" + }, { + "id": "1edca1a8-1e15-489f-8f18-a80bd53c5360", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "none" + }, { + "id": "2897afef-6eef-4205-a0bb-f95cccef7a74", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "nonepass" + }, { + "id": "6c4429c8-7d82-4d87-a58d-a587cff891f6", + "comment": "", + "command": "click", + "target": "name=submit", + "targets": [ + ["name=submit", "name"], + ["css=td:nth-child(1) > input", "css:finder"], + ["xpath=//input[@name='submit']", "xpath:attributes"], + ["xpath=//tr[3]/td/input", "xpath:position"] + ], + "value": "" + }, { + "id": "3eb77106-8fb7-43aa-a72a-27f2960d5393", + "comment": "", + "command": "waitForElementVisible", + "target": "css=p", + "targets": [], + "value": "30000" + }, { + "id": "b826ed10-31a4-487b-ba80-c633ff037839", + "comment": "", + "command": "assertText", + "target": "css=p", + "targets": [ + ["css=p", "css:finder"], + ["xpath=//p", "xpath:position"] + ], + "value": "Your login attempt was not successful, try again.\n\nReason: Bad credentials" + }, { + "id": "5b421e75-d5db-44ff-ac57-2fd8f91c2478", + "comment": "", + "command": "close", + "target": "", + "targets": [], + "value": "" + }] + }], + "suites": [{ + "id": "86d753b7-e7f9-48b0-a95e-ac68deea5457", + "name": "Default Suite", + "persistSession": false, + "parallel": false, + "timeout": 300, + "tests": ["3ee270a9-8a5c-4a17-92e7-ab9b013e7aee"] + }], + "urls": ["http://localhost:10101/"], + "plugins": [] +} diff --git a/backend/src/integration/resources/SHIBUI-1503-3.side b/backend/src/integration/resources/SHIBUI-1503-3.side new file mode 100644 index 000000000..a7d913abd --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-1503-3.side @@ -0,0 +1,192 @@ +{ + "id": "fbdf2699-39a2-4738-85e4-23a058038e05", + "version": "2.0", + "name": "SHIBUI-1503-3", + "url": "http://localhost:10101", + "tests": [{ + "id": "67c3076f-1c47-4104-98ee-d4c3cd6ef870", + "name": "SHIBUI-1503-3", + "commands": [{ + "id": "dd74edbf-87ef-4b2a-8a5a-7b8ab7fc6055", + "comment": "", + "command": "open", + "target": "/login", + "targets": [], + "value": "" + }, { + "id": "4d0aeac6-bdc6-495b-8115-c03b6a818f9c", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "admin" + }, { + "id": "5eda2e43-304c-4e99-9f2a-0d352bb7140d", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "adminpass" + }, { + "id": "fa54f4c6-f1b4-422c-be58-b6c1fef27a47", + "comment": "", + "command": "click", + "target": "name=submit", + "targets": [ + ["name=submit", "name"], + ["css=td:nth-child(1) > input", "css:finder"], + ["xpath=//input[@name='submit']", "xpath:attributes"], + ["xpath=//tr[3]/td/input", "xpath:position"] + ], + "value": "" + }, { + "id": "fe445ea9-b8ac-4186-a814-4cda6968f6d7", + "comment": "", + "command": "waitForElementVisible", + "target": "linkText=Admin", + "targets": [], + "value": "30000" + }, { + "id": "277ab8a3-924d-4f2a-a1d4-7b69ecd623ec", + "comment": "", + "command": "click", + "target": "linkText=Admin", + "targets": [ + ["linkText=Admin", "linkText"], + ["css=.nav-item:nth-child(3) > .nav-link", "css:finder"], + ["xpath=//a[contains(text(),'Admin')]", "xpath:link"], + ["xpath=//a[contains(@href, '/dashboard/admin/management')]", "xpath:href"], + ["xpath=//dashboard-page/div/ul/li[3]/a", "xpath:position"], + ["xpath=//a[contains(.,'Admin')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "659e4909-239b-4895-aa54-8bf3a6bd57cd", + "comment": "", + "command": "waitForElementVisible", + "target": "css=tr:nth-child(3) .form-control", + "targets": [], + "value": "30000" + }, { + "id": "1c973205-111b-4440-afef-bd0e7e13b18c", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(3) .form-control", + "targets": [ + ["css=tr:nth-child(3) .form-control", "css:finder"], + ["xpath=//tr[3]/td[3]/select", "xpath:position"] + ], + "value": "" + }, { + "id": "dc06ff49-c076-4f60-95d1-a42514cc6038", + "comment": "", + "command": "select", + "target": "css=tr:nth-child(3) .form-control", + "targets": [], + "value": "label=ROLE_USER" + }, { + "id": "fb78d880-ffb7-4477-b1af-f9a8593875de", + "comment": "", + "command": "click", + "target": "css=li:nth-child(3) > .nav-link > translate-i18n", + "targets": [ + ["css=li:nth-child(3) > .nav-link > translate-i18n", "css:finder"], + ["xpath=//div[@id='navbar']/ul/li[3]/a/translate-i18n", "xpath:idRelative"], + ["xpath=//li[3]/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Logout')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "01f6bc37-2698-48c9-82f3-51928069ed58", + "comment": "", + "command": "waitForElementEditable", + "target": "name=username", + "targets": [], + "value": "30000" + }, { + "id": "6916ad6c-11db-423a-bb42-ad81287a71b2", + "comment": "", + "command": "type", + "target": "name=username", + "targets": [ + ["name=username", "name"], + ["css=tr:nth-child(1) input", "css:finder"], + ["xpath=//input[@name='username']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "none" + }, { + "id": "c8bf8ea5-1f75-4a40-aca4-9dfa6a6056dc", + "comment": "", + "command": "type", + "target": "name=password", + "targets": [ + ["name=password", "name"], + ["css=tr:nth-child(2) input", "css:finder"], + ["xpath=//input[@name='password']", "xpath:attributes"], + ["xpath=//tr[2]/td[2]/input", "xpath:position"] + ], + "value": "nonepass" + }, { + "id": "ba66c45f-2436-4fe7-a5a9-31b55ffe8118", + "comment": "", + "command": "click", + "target": "name=submit", + "targets": [ + ["name=submit", "name"], + ["css=td:nth-child(1) > input", "css:finder"], + ["xpath=//input[@name='submit']", "xpath:attributes"], + ["xpath=//tr[3]/td/input", "xpath:position"] + ], + "value": "" + }, { + "id": "16d9ba7b-995c-4383-98c0-07d5e779a27d", + "comment": "", + "command": "waitForElementPresent", + "target": "linkText=Metadata Sources", + "targets": [], + "value": "30000" + }, { + "id": "c2dd7259-7ae0-4b4f-a6b8-2592fa799f9c", + "comment": "", + "command": "assertText", + "target": "linkText=Metadata Sources", + "targets": [ + ["linkText=Metadata Sources", "linkText"], + ["css=.nav-item:nth-child(1) > .nav-link", "css:finder"], + ["xpath=//a[contains(text(),'Metadata Sources')]", "xpath:link"], + ["xpath=//a[contains(@href, '/dashboard/metadata/manager/resolvers')]", "xpath:href"], + ["xpath=//dashboard-page/div/ul/li/a", "xpath:position"], + ["xpath=//a[contains(.,'Metadata Sources')]", "xpath:innerText"] + ], + "value": "Metadata Sources" + }, { + "id": "5b9612bd-d0ea-439b-895f-3dc372023578", + "comment": "", + "command": "close", + "target": "", + "targets": [], + "value": "" + }] + }], + "suites": [{ + "id": "173aaf44-c763-416e-ab3c-d5afd5ffcd29", + "name": "Default Suite", + "persistSession": false, + "parallel": false, + "timeout": 300, + "tests": ["67c3076f-1c47-4104-98ee-d4c3cd6ef870"] + }], + "urls": ["http://localhost:10101/"], + "plugins": [] +} \ No newline at end of file From 9a3488144b62f677200356b1e8c87e6ca133ba77 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 29 Oct 2019 10:15:17 -0700 Subject: [PATCH 2/9] SHIBUI-1550 Filtered navigation actions by user role --- ui/src/app/admin/admin.component.ts | 8 +------- .../admin/container/action-required.component.ts | 7 +------ .../admin/container/admin-management.component.ts | 8 +------- ui/src/app/app.component.ts | 13 ++++++++++--- ui/src/app/core/model/action.ts | 1 + ui/src/app/core/reducer/index.ts | 2 ++ ui/src/app/metadata/metadata.module.ts | 4 ++-- 7 files changed, 18 insertions(+), 25 deletions(-) diff --git a/ui/src/app/admin/admin.component.ts b/ui/src/app/admin/admin.component.ts index 409503b6c..ae1469443 100644 --- a/ui/src/app/admin/admin.component.ts +++ b/ui/src/app/admin/admin.component.ts @@ -1,16 +1,10 @@ import { Component } from '@angular/core'; -import * as fromRoot from '../app.reducer'; -import { Store } from '@ngrx/store'; -import { LoadAdminRequest } from './action/admin-collection.action'; - @Component({ selector: 'admin-page', templateUrl: './admin.component.html', styleUrls: [] }) export class AdminComponent { - constructor( - private store: Store - ) {} + constructor() {} } diff --git a/ui/src/app/admin/container/action-required.component.ts b/ui/src/app/admin/container/action-required.component.ts index f504f36e4..7631c963b 100644 --- a/ui/src/app/admin/container/action-required.component.ts +++ b/ui/src/app/admin/container/action-required.component.ts @@ -1,7 +1,4 @@ import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { Store } from '@ngrx/store'; - -import * as fromRoot from '../../app.reducer'; @Component({ selector: 'action-required-page', @@ -11,7 +8,5 @@ import * as fromRoot from '../../app.reducer'; }) export class ActionRequiredPageComponent { - constructor( - private store: Store - ) {} + constructor() {} } diff --git a/ui/src/app/admin/container/admin-management.component.ts b/ui/src/app/admin/container/admin-management.component.ts index fa657d5b5..b52211be4 100644 --- a/ui/src/app/admin/container/admin-management.component.ts +++ b/ui/src/app/admin/container/admin-management.component.ts @@ -1,8 +1,4 @@ import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { Store } from '@ngrx/store'; - -import * as fromRoot from '../../app.reducer'; -import { LoadAdminRequest } from '../action/admin-collection.action'; @Component({ selector: 'admin-management-page', @@ -12,7 +8,5 @@ import { LoadAdminRequest } from '../action/admin-collection.action'; }) export class AdminManagementPageComponent { - constructor( - private store: Store - ) {} + constructor() {} } diff --git a/ui/src/app/app.component.ts b/ui/src/app/app.component.ts index 4554efce8..0f12387dd 100644 --- a/ui/src/app/app.component.ts +++ b/ui/src/app/app.component.ts @@ -1,6 +1,6 @@ import { Component, OnInit, ChangeDetectionStrategy } from '@angular/core'; -import { Observable, of } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; +import { Observable, of, combineLatest } from 'rxjs'; +import { map, catchError, filter } from 'rxjs/operators'; import { Store } from '@ngrx/store'; @@ -44,7 +44,14 @@ export class AppComponent implements OnInit { this.formatted$ = this.version$.pipe(map(this.formatter)); this.isAdmin$ = this.store.select(fromRoot.isCurrentUserAdmin); - this.nav$ = this.navService.emitter; + this.nav$ = combineLatest( + this.store.select(fromRoot.getCurrentUserRole).pipe(filter(r => !!r)), + this.navService.emitter + ).pipe( + map(([role, actions]) => actions.filter( + action => action.restrict ? action.restrict.includes(role) : action + ) + )); } ngOnInit(): void { diff --git a/ui/src/app/core/model/action.ts b/ui/src/app/core/model/action.ts index 2f7e1ca3c..49ad487aa 100644 --- a/ui/src/app/core/model/action.ts +++ b/ui/src/app/core/model/action.ts @@ -4,4 +4,5 @@ export interface NavigationAction { label: string; content: string; icon?: string; + restrict?: string[]; } diff --git a/ui/src/app/core/reducer/index.ts b/ui/src/app/core/reducer/index.ts index f5e5b94c2..bbe53eae6 100644 --- a/ui/src/app/core/reducer/index.ts +++ b/ui/src/app/core/reducer/index.ts @@ -46,4 +46,6 @@ export const getConfigState = createSelector(getCoreFeature, getConfigStateFn); export const getRoles = createSelector(getConfigState, fromConfig.getRoles); export const getUserRoles = createSelector(getRoles, filterRolesFn); +export const getCurrentUserRole = createSelector(getUser, u => u ? u.role : null); + export const isCurrentUserAdmin = createSelector(getUser, isUserAdminFn); diff --git a/ui/src/app/metadata/metadata.module.ts b/ui/src/app/metadata/metadata.module.ts index b116d3d34..3ae18c5bd 100644 --- a/ui/src/app/metadata/metadata.module.ts +++ b/ui/src/app/metadata/metadata.module.ts @@ -16,7 +16,6 @@ import { NavigationService } from '../core/service/navigation.service'; import { MetadataResolver } from './domain/model'; import { AddDraftRequest } from './resolver/action/draft.action'; import * as fromResolver from './resolver/reducer'; -import * as fromProvider from './provider/reducer'; import { Router } from '@angular/router'; @NgModule({ @@ -66,7 +65,8 @@ export class MetadataModule { this.router.navigate(['/metadata', 'provider', 'wizard']); }, category: 'metadata', - icon: 'fa-cubes' + icon: 'fa-cubes', + restrict: ['ROLE_ADMIN'] }); } } From 1d568273f46a27d79c718e20d7d51cafd2a464b3 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 29 Oct 2019 10:20:09 -0700 Subject: [PATCH 3/9] SHIBUI-772 Added plus icon to add entity ID button --- .../widget/filter-target/filter-target.component.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/src/app/schema-form/widget/filter-target/filter-target.component.html b/ui/src/app/schema-form/widget/filter-target/filter-target.component.html index f1e04538a..993b08f3f 100644 --- a/ui/src/app/schema-form/widget/filter-target/filter-target.component.html +++ b/ui/src/app/schema-form/widget/filter-target/filter-target.component.html @@ -92,7 +92,8 @@ [disabled]="search.invalid" (click)="onSelectValue(search.value)" translate="action.add-entity-id"> - Add Entity ID + Add Entity ID   + From 1120bd6436f3c5fd09787f3f037cabda1055546e Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 29 Oct 2019 13:17:54 -0700 Subject: [PATCH 4/9] SHIBUI-1224 Fixed issue with org data --- .../metadata/resolver/action/entity.action.ts | 16 +++++++++---- .../container/resolver-edit-step.component.ts | 4 ++-- .../resolver-wizard-step.component.ts | 10 +++++--- .../resolver/effect/collection.effects.ts | 2 -- .../metadata/resolver/effect/entity.effect.ts | 24 ++++++++++++++++++- .../metadata/resolver/effect/wizard.effect.ts | 11 ++++----- .../resolver/reducer/entity.reducer.spec.ts | 6 ++--- .../resolver/reducer/entity.reducer.ts | 4 ++-- 8 files changed, 54 insertions(+), 23 deletions(-) diff --git a/ui/src/app/metadata/resolver/action/entity.action.ts b/ui/src/app/metadata/resolver/action/entity.action.ts index 490cd6a03..b489ee831 100644 --- a/ui/src/app/metadata/resolver/action/entity.action.ts +++ b/ui/src/app/metadata/resolver/action/entity.action.ts @@ -4,7 +4,8 @@ import { MetadataResolver } from '../../domain/model'; export enum ResolverEntityActionTypes { UPDATE_STATUS = '[Resolver Entity] Update Status', UPDATE_SAVING = '[Resolver Entity] Update Saving', - UPDATE_CHANGES = '[Resolver Entity] Update Changes', + UPDATE_CHANGES_REQUEST = '[Resolver Entity] Update Changes Request', + UPDATE_CHANGES_SUCCESS = '[Resolver Entity] Update Changes Success', CLEAR = '[Resolver Entity] Clear', CANCEL = '[Resolver Entity] Cancel' } @@ -15,8 +16,14 @@ export class UpdateStatus implements Action { constructor(public payload: { [key: string]: string }) { } } -export class UpdateChanges implements Action { - readonly type = ResolverEntityActionTypes.UPDATE_CHANGES; +export class UpdateChangesRequest implements Action { + readonly type = ResolverEntityActionTypes.UPDATE_CHANGES_REQUEST; + + constructor(public payload: MetadataResolver) { } +} + +export class UpdateChangesSuccess implements Action { + readonly type = ResolverEntityActionTypes.UPDATE_CHANGES_SUCCESS; constructor(public payload: MetadataResolver) { } } @@ -41,6 +48,7 @@ export class Cancel implements Action { export type ResolverEntityActionUnion = | UpdateStatus - | UpdateChanges + | UpdateChangesRequest + | UpdateChangesSuccess | UpdateSaving | Clear; diff --git a/ui/src/app/metadata/resolver/container/resolver-edit-step.component.ts b/ui/src/app/metadata/resolver/container/resolver-edit-step.component.ts index 4dc3cc3dc..1a8d0d648 100644 --- a/ui/src/app/metadata/resolver/container/resolver-edit-step.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-edit-step.component.ts @@ -10,7 +10,7 @@ import { LockEditor, UnlockEditor } from '../../../wizard/action/wizard.action'; import * as fromWizard from '../../../wizard/reducer'; import { withLatestFrom, map, distinctUntilChanged, filter, takeUntil } from 'rxjs/operators'; -import { UpdateChanges } from '../action/entity.action'; +import { UpdateChangesRequest } from '../action/entity.action'; import { FormControl } from '@angular/forms'; @Component({ @@ -103,7 +103,7 @@ export class ResolverEditStepComponent implements OnDestroy { map(([valueChange, definition, resolver, changes]) => definition.parser({ ...resolver, ...changes, ...valueChange })) ) .subscribe(changes => { - this.store.dispatch(new UpdateChanges(changes)); + this.store.dispatch(new UpdateChangesRequest(changes)); }); this.statusChangeEmitted$ diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts index a4df116f8..68840c70e 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard-step.component.ts @@ -6,7 +6,7 @@ import { Store } from '@ngrx/store'; import * as fromResolver from '../reducer'; import * as fromWizard from '../../../wizard/reducer'; -import { UpdateStatus, UpdateChanges } from '../action/entity.action'; +import { UpdateStatus, UpdateChangesRequest } from '../action/entity.action'; import { Wizard } from '../../../wizard/model'; import { MetadataResolver } from '../../domain/model'; @@ -82,10 +82,14 @@ export class ResolverWizardStepComponent implements OnDestroy { map(([ changes, definition ]) => definition.parser(changes.value)) ) .subscribe(changes => { - this.store.dispatch(new UpdateChanges(changes)); + this.store.dispatch(new UpdateChangesRequest(changes)); }); - this.statusChangeEmitted$.pipe(distinctUntilChanged()).subscribe(errors => this.updateStatus(errors)); + this.statusChangeEmitted$ + .pipe(distinctUntilChanged()) + .subscribe(errors => { + this.updateStatus(errors); + }); this.store.select(fromWizard.getWizardIndex).subscribe(i => this.currentPage = i); } diff --git a/ui/src/app/metadata/resolver/effect/collection.effects.ts b/ui/src/app/metadata/resolver/effect/collection.effects.ts index 2a92b0242..d818aacd8 100644 --- a/ui/src/app/metadata/resolver/effect/collection.effects.ts +++ b/ui/src/app/metadata/resolver/effect/collection.effects.ts @@ -26,7 +26,6 @@ import { CreateResolverFromUrlRequest } from '../action/collection.action'; import * as draftActions from '../action/draft.action'; -import { } from '../action/collection.action'; import { ResolverService } from '../../domain/service/resolver.service'; import { removeNulls } from '../../../shared/util'; import { AddNotification } from '../../../notification/action/notification.action'; @@ -34,7 +33,6 @@ import { Notification, NotificationType } from '../../../notification/model/noti import { I18nService } from '../../../i18n/service/i18n.service'; import * as fromRoot from '../../../app.reducer'; import * as fromI18n from '../../../i18n/reducer'; -import { FileBackedHttpMetadataResolver } from '../../domain/entity'; import { UpdateSaving } from '../action/entity.action'; diff --git a/ui/src/app/metadata/resolver/effect/entity.effect.ts b/ui/src/app/metadata/resolver/effect/entity.effect.ts index 98a4b5891..d28f8a3db 100644 --- a/ui/src/app/metadata/resolver/effect/entity.effect.ts +++ b/ui/src/app/metadata/resolver/effect/entity.effect.ts @@ -5,11 +5,14 @@ import { switchMap, map, withLatestFrom, tap } from 'rxjs/operators'; import * as fromResolver from '../reducer'; import * as fromRoot from '../../../app.reducer'; +import * as fromWizard from '../../../wizard/reducer'; import { ResolverEntityActionTypes, Clear, - Cancel + Cancel, + UpdateChangesRequest, + UpdateChangesSuccess } from '../action/entity.action'; import * as provider from '../action/collection.action'; @@ -24,6 +27,25 @@ import { ContentionService } from '../../../contention/service/contention.servic @Injectable() export class EntityEffects { + @Effect() + updateChanges$ = this.actions$.pipe( + ofType(ResolverEntityActionTypes.UPDATE_CHANGES_REQUEST), + map(action => action.payload), + withLatestFrom( + this.store.select(fromResolver.getEntityChanges), + this.store.select(fromWizard.getSchema) + ), + map(([changes, stored, schema]) => { + const props = Object.keys(schema.properties); + const diffed = props.reduce((changeObj, prop) => { + changeObj[prop] = !changes.hasOwnProperty(prop) && stored.hasOwnProperty(prop) ? null : changes[prop]; + return changeObj; + }, {}); + const update = { ...stored, ...diffed }; + return new UpdateChangesSuccess(update); + }) + ); + @Effect() cancelChanges$ = this.actions$.pipe( ofType(ResolverEntityActionTypes.CANCEL), diff --git a/ui/src/app/metadata/resolver/effect/wizard.effect.ts b/ui/src/app/metadata/resolver/effect/wizard.effect.ts index 9f94182f3..04dc7ca40 100644 --- a/ui/src/app/metadata/resolver/effect/wizard.effect.ts +++ b/ui/src/app/metadata/resolver/effect/wizard.effect.ts @@ -5,9 +5,9 @@ import { map, filter, tap, withLatestFrom } from 'rxjs/operators'; import { Store } from '@ngrx/store'; import { - UpdateChanges, Clear, - ResolverEntityActionTypes + ResolverEntityActionTypes, + UpdateChangesSuccess } from '../action/entity.action'; import { ResolverCollectionActionTypes, @@ -17,18 +17,17 @@ import { import * as fromResolver from '../reducer'; import { EntityDraftService } from '../../domain/service/draft.service'; -import { UpdateDraftRequest, SelectDraftSuccess, DraftActionTypes } from '../action/draft.action'; +import { UpdateDraftRequest } from '../action/draft.action'; @Injectable() export class WizardEffects { @Effect() updateResolver$ = this.actions$.pipe( - ofType(ResolverEntityActionTypes.UPDATE_CHANGES), + ofType(ResolverEntityActionTypes.UPDATE_CHANGES_SUCCESS), map(action => action.payload), filter(provider => !provider.createdDate), - withLatestFrom(this.store.select(fromResolver.getSelectedDraft)), - map(([provider, draft]) => new UpdateDraftRequest({ ...draft, ...provider })) + map((provider) => new UpdateDraftRequest({ ...provider })) ); @Effect() diff --git a/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts b/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts index 630b0b998..acde92bc1 100644 --- a/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts +++ b/ui/src/app/metadata/resolver/reducer/entity.reducer.spec.ts @@ -1,9 +1,9 @@ import { reducer } from './entity.reducer'; import * as fromEntity from './entity.reducer'; import { - UpdateChanges, UpdateStatus, - Clear + Clear, + UpdateChangesSuccess } from '../action/entity.action'; import { MetadataResolver } from '../../domain/model'; @@ -42,7 +42,7 @@ describe('Entity Reducer', () => { describe('Entity Update Changes', () => { it('should add changes of the provided form', () => { - const action = new UpdateChanges(changes); + const action = new UpdateChangesSuccess(changes); const result = reducer(initialState, action); expect(result).toEqual( { diff --git a/ui/src/app/metadata/resolver/reducer/entity.reducer.ts b/ui/src/app/metadata/resolver/reducer/entity.reducer.ts index 819eacd11..158ed193c 100644 --- a/ui/src/app/metadata/resolver/reducer/entity.reducer.ts +++ b/ui/src/app/metadata/resolver/reducer/entity.reducer.ts @@ -16,10 +16,10 @@ export const initialState: EntityState = { export function reducer(state = initialState, action: ResolverEntityActionUnion): EntityState { switch (action.type) { - case ResolverEntityActionTypes.UPDATE_CHANGES: { + case ResolverEntityActionTypes.UPDATE_CHANGES_SUCCESS: { return { ...state, - changes: { ...state.changes, ...action.payload } + changes: { ...action.payload } }; } case ResolverEntityActionTypes.UPDATE_STATUS: { From d59d7544d267b6163f282b83100f600110fe3d02 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 29 Oct 2019 13:46:48 -0700 Subject: [PATCH 5/9] SHIBUI-1552 Fixed issue with loading in Safari --- ui/browserslist | 3 +-- ui/tsconfig.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/browserslist b/ui/browserslist index 80848532e..e8ec33b68 100644 --- a/ui/browserslist +++ b/ui/browserslist @@ -8,5 +8,4 @@ > 0.5% last 2 versions Firefox ESR -not dead -not IE 9-11 # For IE 9-11 support, remove 'not'. \ No newline at end of file +IE 11 \ No newline at end of file diff --git a/ui/tsconfig.json b/ui/tsconfig.json index 588c8d782..5731a73e0 100644 --- a/ui/tsconfig.json +++ b/ui/tsconfig.json @@ -10,7 +10,7 @@ "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "downlevelIteration": true, - "target": "es2015", + "target": "es5", "typeRoots": [ "node_modules/@types" ], From 18b483fe04c7404d5112f39bef213ca2f86eec27 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Thu, 31 Oct 2019 14:07:05 -0700 Subject: [PATCH 6/9] SHIBUI-1559 Fixed issue with unsaved changes modal --- .../metadata/resolver/container/resolver-wizard.component.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts index bd7c6e437..46416f78a 100644 --- a/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts +++ b/ui/src/app/metadata/resolver/container/resolver-wizard.component.ts @@ -149,7 +149,7 @@ export class ResolverWizardComponent implements OnDestroy, CanComponentDeactivat } get blacklist(): string[] { - return ['id', 'resourceId']; + return ['id', 'resourceId', 'entityId', 'serviceProviderName']; } hasChanges(changes: MetadataResolver): boolean { From 4dcda6b74ffc95c49b2108a6652f70f88316a5ba Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Fri, 1 Nov 2019 12:04:04 -0700 Subject: [PATCH 7/9] SHIBUI-1208 Fixed issue with filters --- .../container/provider-edit-step.component.ts | 21 ++++++++++++------- .../container/provider-edit.component.ts | 5 ++++- ui/src/app/wizard/reducer/index.ts | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ui/src/app/metadata/provider/container/provider-edit-step.component.ts b/ui/src/app/metadata/provider/container/provider-edit-step.component.ts index c869c8e9c..26eac92a4 100644 --- a/ui/src/app/metadata/provider/container/provider-edit-step.component.ts +++ b/ui/src/app/metadata/provider/container/provider-edit-step.component.ts @@ -95,6 +95,7 @@ export class ProviderEditStepComponent implements OnDestroy { }), filter(({ model, definition }) => definition && model), map(({ model, definition }) => { + // console.log(model, definition.formatter(model)); return definition ? definition.formatter(model) : {}; }) ); @@ -104,14 +105,18 @@ export class ProviderEditStepComponent implements OnDestroy { withLatestFrom(this.definition$, this.store.select(fromProvider.getSelectedProvider)), filter(([ changes, definition, provider ]) => definition && changes && provider), map(([ changes, definition, provider ]) => { - const parsed = definition.parser(changes); - return ({ - ...parsed, - metadataFilters: [ - ...provider.metadataFilters, - ...(parsed.metadataFilters || []) - ] - }); + const appliedFilters = changes && changes.metadataFilters ? { + ...changes, + metadataFilters: Object.keys(changes.metadataFilters).reduce((filters, filterType) => ({ + ...filters, + [filterType]: { + ...provider.metadataFilters.find(f => f['@type'] === filterType) || {}, + ...changes.metadataFilters[filterType] + } + }), {}) + } : changes; + const parsed = definition.parser(appliedFilters); + return parsed; }) ) .subscribe(changes => this.store.dispatch(new UpdateProvider(changes))); diff --git a/ui/src/app/metadata/provider/container/provider-edit.component.ts b/ui/src/app/metadata/provider/container/provider-edit.component.ts index ef37af038..199071b11 100644 --- a/ui/src/app/metadata/provider/container/provider-edit.component.ts +++ b/ui/src/app/metadata/provider/container/provider-edit.component.ts @@ -42,6 +42,8 @@ export class ProviderEditComponent implements OnDestroy, CanComponentDeactivate formats = NAV_FORMATS; + latest$: Observable; + constructor( private store: Store, private router: Router, @@ -70,7 +72,8 @@ export class ProviderEditComponent implements OnDestroy, CanComponentDeactivate }); this.provider$.subscribe(p => this.provider = p); - this.store.select(fromProvider.getEntityChanges).subscribe(changes => this.latest = changes); + this.latest$ = this.store.select(fromProvider.getEntityChanges); + this.latest$.subscribe(changes => this.latest = changes); this.canFilter$ = this.definition$.pipe(map(def => FilterableProviders.indexOf(def.type) > -1)); } diff --git a/ui/src/app/wizard/reducer/index.ts b/ui/src/app/wizard/reducer/index.ts index 255710be0..ca4cdb0f7 100644 --- a/ui/src/app/wizard/reducer/index.ts +++ b/ui/src/app/wizard/reducer/index.ts @@ -48,7 +48,7 @@ export const getWizardDefinition = createSelector(getState, fromWizard.getDefini export const getSchemaPath = (wizard: Wizard) => wizard ? wizard.schema : null; export const getSplitSchema = (schema: any, step: WizardStep) => { - if (!schema || !step.fields || !step.fields.length || !schema.properties) { + if (!schema || !step || !step.fields || !step.fields.length || !schema.properties) { return schema; } const keys = Object.keys(schema.properties).filter(key => step.fields.indexOf(key) > -1); From 31a73f44502943438b83c5c4130ac2c45b7fb928 Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 5 Nov 2019 08:37:25 -0700 Subject: [PATCH 8/9] SHIBUI-1576 Fixed issue with incomplete sources --- .../model/wizards/metadata-source-base.ts | 3 +++ .../effect/draft-collection.effects.ts | 3 +-- .../metadata/resolver/effect/wizard.effect.ts | 23 ++++++++----------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts b/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts index 360979782..54ad0d58a 100644 --- a/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts +++ b/ui/src/app/metadata/domain/model/wizards/metadata-source-base.ts @@ -56,6 +56,9 @@ export class MetadataSourceBase implements Wizard { }; parser(changes: Partial, schema?: any): any { + if (!changes.organization) { + changes.organization = {}; + } return changes; } diff --git a/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts b/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts index 41c21aae3..07f2d4d24 100644 --- a/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts +++ b/ui/src/app/metadata/resolver/effect/draft-collection.effects.ts @@ -15,8 +15,7 @@ import * as actions from '../action/draft.action'; import { EntityDraftService } from '../../domain/service/draft.service'; import * as fromResolver from '../reducer'; import { Store } from '@ngrx/store'; -import { Clear } from '../action/entity.action'; -import { ClearWizard } from '../../../wizard/action/wizard.action'; +import { MetadataResolver } from '../../domain/model'; export const getPayload = (action: any) => action.payload; diff --git a/ui/src/app/metadata/resolver/effect/wizard.effect.ts b/ui/src/app/metadata/resolver/effect/wizard.effect.ts index 04dc7ca40..a8523d2c2 100644 --- a/ui/src/app/metadata/resolver/effect/wizard.effect.ts +++ b/ui/src/app/metadata/resolver/effect/wizard.effect.ts @@ -1,8 +1,6 @@ import { Injectable } from '@angular/core'; import { Effect, Actions, ofType } from '@ngrx/effects'; -import { ActivatedRoute, Router } from '@angular/router'; -import { map, filter, tap, withLatestFrom } from 'rxjs/operators'; -import { Store } from '@ngrx/store'; +import { map, filter, withLatestFrom } from 'rxjs/operators'; import { Clear, @@ -13,11 +11,10 @@ import { ResolverCollectionActionTypes, AddResolverSuccess } from '../action/collection.action'; - -import * as fromResolver from '../reducer'; - -import { EntityDraftService } from '../../domain/service/draft.service'; import { UpdateDraftRequest } from '../action/draft.action'; +import * as fromRoot from '../../../app.reducer'; +import { Store } from '@ngrx/store'; +import { getSelectedDraftId } from '../reducer'; @Injectable() export class WizardEffects { @@ -27,7 +24,10 @@ export class WizardEffects { ofType(ResolverEntityActionTypes.UPDATE_CHANGES_SUCCESS), map(action => action.payload), filter(provider => !provider.createdDate), - map((provider) => new UpdateDraftRequest({ ...provider })) + withLatestFrom(this.store.select(getSelectedDraftId)), + map(([provider, id]) => { + return new UpdateDraftRequest({ id, ...provider }); + }) ); @Effect() @@ -38,10 +38,7 @@ export class WizardEffects { ); constructor( - private store: Store, - private actions$: Actions, - private draftService: EntityDraftService, - private activatedRoute: ActivatedRoute, - private router: Router + private store: Store, + private actions$: Actions ) { } } From b380c70a08e95effe3367455d4b0b4636212afaa Mon Sep 17 00:00:00 2001 From: Ryan Mathis Date: Tue, 5 Nov 2019 13:14:42 -0700 Subject: [PATCH 9/9] SHIBUI-1576 cleanup --- .../configuration/container/restore-edit.component.ts | 6 ++---- .../provider/container/provider-edit-step.component.ts | 5 +---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/ui/src/app/metadata/configuration/container/restore-edit.component.ts b/ui/src/app/metadata/configuration/container/restore-edit.component.ts index 7bd939ee4..3ca9c6648 100644 --- a/ui/src/app/metadata/configuration/container/restore-edit.component.ts +++ b/ui/src/app/metadata/configuration/container/restore-edit.component.ts @@ -1,5 +1,5 @@ import { Component } from '@angular/core'; -import { Observable, of } from 'rxjs'; +import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; import { ConfigurationState, @@ -36,9 +36,7 @@ export class RestoreEditComponent { constructor( private store: Store - ) { - // this.status$.subscribe(console.log); - } + ) {} save() { this.store.dispatch(new RestoreVersionRequest()); diff --git a/ui/src/app/metadata/provider/container/provider-edit-step.component.ts b/ui/src/app/metadata/provider/container/provider-edit-step.component.ts index 26eac92a4..8a31e4592 100644 --- a/ui/src/app/metadata/provider/container/provider-edit-step.component.ts +++ b/ui/src/app/metadata/provider/container/provider-edit-step.component.ts @@ -94,10 +94,7 @@ export class ProviderEditStepComponent implements OnDestroy { }); }), filter(({ model, definition }) => definition && model), - map(({ model, definition }) => { - // console.log(model, definition.formatter(model)); - return definition ? definition.formatter(model) : {}; - }) + map(({ model, definition }) => definition ? definition.formatter(model) : {}) ); this.valueChangeEmitted$.pipe(