diff --git a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerVersionEndpointsIntegrationTests.groovy b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerVersionEndpointsIntegrationTests.groovy index 99b5810ce..82b143c00 100644 --- a/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerVersionEndpointsIntegrationTests.groovy +++ b/backend/src/enversTest/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntityDescriptorControllerVersionEndpointsIntegrationTests.groovy @@ -1,11 +1,22 @@ package edu.internet2.tier.shibboleth.admin.ui.controller import edu.internet2.tier.shibboleth.admin.ui.domain.EntityDescriptor +import edu.internet2.tier.shibboleth.admin.ui.domain.Organization +import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationDisplayName +import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationName +import edu.internet2.tier.shibboleth.admin.ui.domain.OrganizationURL import edu.internet2.tier.shibboleth.admin.ui.domain.frontend.EntityDescriptorRepresentation import edu.internet2.tier.shibboleth.admin.ui.repository.EntityDescriptorRepository +import groovy.json.JsonOutput +import groovy.json.JsonSlurper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.web.client.TestRestTemplate +import org.springframework.http.HttpEntity +import org.springframework.http.HttpHeaders +import org.springframework.http.HttpMethod +import org.springframework.http.MediaType +import org.springframework.test.annotation.DirtiesContext import org.springframework.test.context.ActiveProfiles import spock.lang.Specification @@ -100,6 +111,46 @@ class EntityDescriptorControllerVersionEndpointsIntegrationTests extends Specifi edv2.body.serviceProviderName == 'SP2' } + @DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) + def 'SHIBUI-1414'() { + given: + def ed = new EntityDescriptor(entityID: 'testme', serviceProviderName: 'testme').with { + entityDescriptorRepository.save(it) + }.with { + it.setOrganization(new Organization().with { + it.organizationNames = [new OrganizationName(value: 'testme', XMLLang: 'en')] + it.organizationDisplayNames = [new OrganizationDisplayName(value: 'testme', XMLLang: 'en')] + it.organizationURLs = [new OrganizationURL(value: 'http://testme.org', XMLLang: 'en')] + it + }) + entityDescriptorRepository.save(it) + } + + when: + def headers = new HttpHeaders().with { + it.set(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) + it + } + + def allVersions = getAllEntityDescriptorVersions(ed.resourceId, List) + def edv1 = getEntityDescriptorForVersion(ed.resourceId, allVersions.body[0].id, String).body + def tedv2 = getEntityDescriptorForVersion(ed.resourceId, allVersions.body[1].id, EntityDescriptorRepresentation).body + + def aedv1 = new JsonSlurper().parseText(edv1).with { + it.put('version', tedv2.version) + it + }.with { + JsonOutput.toJson(it) + } + + def request = new HttpEntity(aedv1, headers) + def response = this.restTemplate.exchange("/api/EntityDescriptor/${ed.resourceId}", HttpMethod.PUT, request, String) + + then: + response.statusCodeValue != 400 + noExceptionThrown() + } + private getAllEntityDescriptorVersions(String resourceId, responseType) { this.restTemplate.getForEntity(resourceUriFor(ALL_VERSIONS_URI, resourceId), responseType) } 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 9db1c4f68..1de0ffc72 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 @@ -119,6 +119,7 @@ class SeleniumSIDETest extends Specification { // 'SHIBUI-1335: Verify Local Dynamic Metadata Provider Filters' | '/SHIBUI-1335-3.side' // 'SHIBUI-1335: Verify Dynamic HTTP Metadata Provider Filters' | '/SHIBUI-1335-4.side' 'SHIBUI-1392: Verify provider with script filter is persistable' | '/SHIBUI-1392.side' + 'SHIBUI-1361: Verify dates display in proper format' | '/SHIBUI-1361.side' } } diff --git a/backend/src/integration/resources/SHIBUI-1334-1.side b/backend/src/integration/resources/SHIBUI-1334-1.side index 79c98c30a..0dd5e38c2 100644 --- a/backend/src/integration/resources/SHIBUI-1334-1.side +++ b/backend/src/integration/resources/SHIBUI-1334-1.side @@ -2219,7 +2219,7 @@ "id": "c2d29077-30c4-45cf-81c9-b5790294e11e", "comment": "", "command": "click", - "target": "css=.btn-info > translate-i18n", + "target": "css=.btn-info", "targets": [ ["css=.btn-info > translate-i18n", "css:finder"], ["xpath=//div[2]/button/translate-i18n", "xpath:position"], @@ -2230,7 +2230,7 @@ "id": "f2e3d420-5cf5-4165-94da-41688839cf82", "comment": "", "command": "click", - "target": "css=.btn-link:nth-child(1) > translate-i18n", + "target": "css=.btn-link:nth-child(1)", "targets": [ ["css=.btn-link:nth-child(1) > translate-i18n", "css:finder"], ["xpath=//div[@id='navigation']/div/a/translate-i18n", "xpath:idRelative"], @@ -2253,7 +2253,7 @@ "id": "68972f7d-8268-4701-865c-585a39987208", "comment": "", "command": "click", - "target": "css=tr:nth-child(2) .custom-control-label", + "target": "css=tr:nth-child(3) .custom-control-label", "targets": [ ["css=tr:nth-child(2) .custom-control-label", "css:finder"], ["xpath=//tr[2]/td/div/label", "xpath:position"] @@ -2270,6 +2270,13 @@ ["xpath=//button[contains(.,'Compare Selected(2)')]", "xpath:innerText"] ], "value": "" + }, { + "id": "98aafaee-a430-4a2d-9aa5-b4c9ce0c4908", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.mb-4:nth-child(2) primitive-property:nth-child(1) .d-block:nth-child(2)", + "targets": [], + "value": "10000" }, { "id": "5a976e2c-dc5f-4021-9cc6-3cad12e771ea", "comment": "", diff --git a/backend/src/integration/resources/SHIBUI-1334-2.side b/backend/src/integration/resources/SHIBUI-1334-2.side index 6679cf490..646217428 100644 --- a/backend/src/integration/resources/SHIBUI-1334-2.side +++ b/backend/src/integration/resources/SHIBUI-1334-2.side @@ -119,6 +119,13 @@ ["xpath=//li[2]/button", "xpath:position"] ], "value": "" + }, { + "id": "d072327c-78b4-4bdb-8020-b825cd26592d", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/xmlId", + "targets": [], + "value": "10000" }, { "id": "86262eda-4a44-41b0-b7aa-fa46406e2601", "comment": "", @@ -578,15 +585,9 @@ }, { "id": "5636ef67-71fb-4bca-ba58-7ecf926c7bf0", "comment": "", - "command": "click", - "target": "id=/xmlId", - "targets": [ - ["id=/xmlId", "id"], - ["name=field38", "name"], - ["css=#\\/xmlId", "css:finder"], - ["xpath=//input[@id='/xmlId']", "xpath:attributes"], - ["xpath=//custom-string/div/input", "xpath:position"] - ], + "command": "pause", + "target": "5000", + "targets": [], "value": "" }, { "id": "7d641e58-47ce-4d20-908c-e0002ff73cfa", @@ -600,7 +601,14 @@ ["xpath=//input[@id='/xmlId']", "xpath:attributes"], ["xpath=//custom-string/div/input", "xpath:position"] ], - "value": "123 v2" + "value": "123 version 2" + }, { + "id": "b78c81e9-41ac-41db-837a-0db6bd4f77eb", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" }, { "id": "247b04c1-e690-42bc-ae15-dfbedb44d2e9", "comment": "", @@ -624,6 +632,13 @@ ["xpath=//button[contains(.,'Save')]", "xpath:innerText"] ], "value": "" + }, { + "id": "eb08417b-b8f0-46dc-9e32-e8daf3bc205d", + "comment": "", + "command": "pause", + "target": "2000", + "targets": [], + "value": "" }, { "id": "cf005a45-74ae-4f7a-a53c-ed59d63f7114", "comment": "", @@ -695,19 +710,19 @@ "command": "assertText", "target": "css=.d-block > primitive-property:nth-child(2) .d-block:nth-child(2)", "targets": [ - ["css=.d-block > primitive-property:nth-child(2) .d-block:nth-child(2)", "css:finder"], - ["xpath=//primitive-property[2]/div/span[2]", "xpath:position"], + ["css=.d-block > primitive-property:nth-child(4) .d-block:nth-child(2)", "css:finder"], + ["xpath=//primitive-property[4]/div/span[2]", "xpath:position"], ["xpath=//span[contains(.,'123 v2')]", "xpath:innerText"] ], - "value": "123 v2" + "value": "123 version 2" }, { "id": "a13198b9-7827-47e2-ade3-143b981d34ee", "comment": "", "command": "assertText", "target": "css=.d-block > primitive-property:nth-child(2) .d-block:nth-child(3)", "targets": [ - ["css=.d-block > primitive-property:nth-child(2) .d-block:nth-child(3)", "css:finder"], - ["xpath=//primitive-property[2]/div/span[3]", "xpath:position"] + ["css=.d-block > primitive-property:nth-child(4) .d-block:nth-child(3)", "css:finder"], + ["xpath=//primitive-property[4]/div/span[3]", "xpath:position"] ], "value": "123" }, { @@ -716,8 +731,8 @@ "command": "assertText", "target": "css=.d-block > primitive-property:nth-child(10) .d-block:nth-child(2)", "targets": [ - ["css=.d-block > primitive-property:nth-child(10) .d-block:nth-child(2)", "css:finder"], - ["xpath=//primitive-property[10]/div/span[2]", "xpath:position"] + ["css=.d-block > primitive-property:nth-child(12) .d-block:nth-child(2)", "css:finder"], + ["xpath=//primitive-property[12]/div/span[2]", "xpath:position"] ], "value": "false" }, { @@ -726,8 +741,8 @@ "command": "assertText", "target": "css=.d-block > primitive-property:nth-child(10) .d-block:nth-child(3)", "targets": [ - ["css=.d-block > primitive-property:nth-child(10) .d-block:nth-child(3)", "css:finder"], - ["xpath=//primitive-property[10]/div/span[3]", "xpath:position"] + ["css=.d-block > primitive-property:nth-child(12) .d-block:nth-child(3)", "css:finder"], + ["xpath=//primitive-property[12]/div/span[3]", "xpath:position"] ], "value": "true" }, { @@ -782,17 +797,11 @@ ], "value": "" }, { - "id": "78967fb5-8f61-46ce-9c14-9b6ceb12b03a", + "id": "270a048e-b903-4bc1-b95b-06ffbdef99de", "comment": "", - "command": "click", - "target": "css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", - "targets": [ - ["css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", "css:finder"], - ["xpath=(//button[@type='button'])[2]", "xpath:attributes"], - ["xpath=//div[@id='/httpMetadataResolverAttributes/connectionRequestTimeout-container']/div/div/button", "xpath:idRelative"], - ["xpath=//auto-complete/div/div/div/button", "xpath:position"], - ["xpath=//button[contains(.,'Toggle Dropdown')]", "xpath:innerText"] - ], + "command": "pause", + "target": "3000", + "targets": [], "value": "" }, { "id": "1cde012c-d521-4fd5-a7d5-7a680bba0e7b", @@ -806,7 +815,14 @@ ], "value": "" }, { - "id": "d00ecf98-7425-467c-acbb-3b39918e3462", + "id": "863e9f5e-a3d6-47e9-8b65-de639029812a", + "comment": "", + "command": "waitForElementVisible", + "target": "css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", + "targets": [], + "value": "10000" + }, { + "id": "78967fb5-8f61-46ce-9c14-9b6ceb12b03a", "comment": "", "command": "click", "target": "css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", @@ -818,6 +834,13 @@ ["xpath=//button[contains(.,'Toggle Dropdown')]", "xpath:innerText"] ], "value": "" + }, { + "id": "8277f894-0bbd-41f7-b3bb-1aba2a0f80be", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/httpMetadataResolverAttributes/connectionRequestTimeout__option--1", + "targets": [], + "value": "10000" }, { "id": "8ba62572-354d-47f4-bb72-f9309c1cb201", "comment": "", @@ -844,6 +867,13 @@ ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/div/div/button", "xpath:position"] ], "value": "" + }, { + "id": "7014a534-b908-482f-85d2-7f7031741b04", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/httpMetadataResolverAttributes/connectionTimeout__option--2", + "targets": [], + "value": "10000" }, { "id": "337ac160-7990-425f-83da-2788d8a0985e", "comment": "", @@ -869,6 +899,13 @@ ["xpath=//div[3]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/div/div/button", "xpath:position"] ], "value": "" + }, { + "id": "c28e3ee6-e536-4eb7-914b-896b2ec2cb9e", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/httpMetadataResolverAttributes/socketTimeout__option--3", + "targets": [], + "value": "10000" }, { "id": "34693225-4754-4b27-92ee-3e37304a8cd7", "comment": "", @@ -893,6 +930,13 @@ ["xpath=//button[contains(.,'Save')]", "xpath:innerText"] ], "value": "" + }, { + "id": "c3ad6c24-736a-492a-8952-b368e123d8e1", + "comment": "", + "command": "waitForElementVisible", + "target": "linkText=Test Metadata Provider", + "targets": [], + "value": "10000" }, { "id": "8868c054-2e6a-403e-ba2b-499a56730d71", "comment": "", @@ -911,7 +955,7 @@ "id": "0092cd5c-a885-4a48-a233-b3af447b02bc", "comment": "", "command": "click", - "target": "css=.btn-link:nth-child(1) > translate-i18n", + "target": "css=.btn-link:nth-child(1)", "targets": [ ["css=.btn-link:nth-child(1) > translate-i18n", "css:finder"], ["xpath=//div[@id='navigation']/div/a/translate-i18n", "xpath:idRelative"], diff --git a/backend/src/integration/resources/SHIBUI-1361.side b/backend/src/integration/resources/SHIBUI-1361.side new file mode 100644 index 000000000..ae87cd2b7 --- /dev/null +++ b/backend/src/integration/resources/SHIBUI-1361.side @@ -0,0 +1,1231 @@ +{ + "id": "6c70c319-3e73-4a13-8ee7-d9da5f802b83", + "version": "2.0", + "name": "SHIBUI-1361", + "url": "http://localhost:10101", + "tests": [{ + "id": "1e7a4ca4-b2e6-4e5a-8e38-823ae8a1e20d", + "name": "SHIBUI-1361", + "commands": [{ + "id": "58401038-5239-4643-b370-d7012a6f9486", + "comment": "", + "command": "store", + "target": "^[A-Z][a-z]{2} [0-9][0-9]?, [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}(.*)?$", + "targets": [], + "value": "dateRegex" + }, { + "id": "29bb3186-81c8-4b3e-a9d9-5ff55d225878", + "comment": "", + "command": "open", + "target": "/login", + "targets": [], + "value": "" + }, { + "id": "302b949f-39b8-4060-813b-d827cf62dff4", + "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": "a7910a51-e40e-4cdb-a72e-5f2cfd1b3656", + "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": "6636b5f6-2b97-4be9-9fc7-44d6b48b8abf", + "comment": "", + "command": "sendKeys", + "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": "${KEY_ENTER}" + }, { + "id": "e7a98419-36c7-4b0f-a99d-087144f6a417", + "comment": "", + "command": "click", + "target": "css=.fa-plus-circle", + "targets": [ + ["css=.fa-plus-circle", "css:finder"], + ["xpath=//button[@id='addNewDropdown']/i", "xpath:idRelative"], + ["xpath=//i", "xpath:position"] + ], + "value": "" + }, { + "id": "74fef022-3979-4bed-9226-b25114514976", + "comment": "", + "command": "click", + "target": "linkText=Metadata Provider", + "targets": [ + ["linkText=Metadata Provider", "linkText"], + ["css=.nav-link:nth-child(2)", "css:finder"], + ["xpath=//div[@id='navbar']/ul/li/div/a[2]", "xpath:idRelative"], + ["xpath=(//a[contains(@href, '')])[3]", "xpath:href"], + ["xpath=//a[2]", "xpath:position"] + ], + "value": "" + }, { + "id": "b49d6ed7-75ea-4be8-9a79-c7fd83287aa0", + "comment": "", + "command": "click", + "target": "id=/name", + "targets": [ + ["id=/name", "id"], + ["name=field1", "name"], + ["css=#\\/name", "css:finder"], + ["xpath=//input[@id='/name']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "" + }, { + "id": "54dc29f7-bbe0-4c2b-a76e-e67a61f57a96", + "comment": "", + "command": "type", + "target": "id=/name", + "targets": [ + ["id=/name", "id"], + ["name=field1", "name"], + ["css=#\\/name", "css:finder"], + ["xpath=//input[@id='/name']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "Test Metadata Provider" + }, { + "id": "add874d5-e3b2-4412-8039-2b9d2619ed19", + "comment": "", + "command": "select", + "target": "id=/type", + "targets": [ + ["css=select-component > .widget", "css:finder"], + ["xpath=//select-component/div", "xpath:position"] + ], + "value": "label=FileBackedHttpMetadataProvider" + }, { + "id": "1cc352f4-0d71-4a3e-9399-1d9932816efc", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[2]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "79f8f28b-8bcf-464a-850f-eb10552a9390", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/xmlId", + "targets": [], + "value": "10000" + }, { + "id": "86262eda-4a44-41b0-b7aa-fa46406e2601", + "comment": "", + "command": "type", + "target": "id=/xmlId", + "targets": [ + ["id=field7", "id"], + ["name=field7", "name"], + ["css=#field7", "css:finder"], + ["xpath=//input[@id='field7']", "xpath:attributes"], + ["xpath=//input", "xpath:position"] + ], + "value": "123" + }, { + "id": "26cc765d-98c1-414c-97d8-4c7e5c6ab7e2", + "comment": "", + "command": "type", + "target": "id=/metadataURL", + "targets": [ + ["id=field8", "id"], + ["name=field8", "name"], + ["css=#field8", "css:finder"], + ["xpath=//input[@id='field8']", "xpath:attributes"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/custom-string/div/input", "xpath:position"] + ], + "value": "https://idp.unicon.net/idp/shibboleth" + }, { + "id": "f0459917-b2a1-4e3c-8800-25273965129f", + "comment": "", + "command": "click", + "target": "id=/initializeFromBackupFile.false", + "targets": [ + ["id=/initializeFromBackupFile.false", "id"], + ["css=#\\/initializeFromBackupFile\\.false", "css:finder"], + ["xpath=//input[@id='/initializeFromBackupFile.false']", "xpath:attributes"], + ["xpath=//div[2]/label/input", "xpath:position"] + ], + "value": "" + }, { + "id": "5b37cf08-77b9-4091-94f9-c0d539c9010d", + "comment": "", + "command": "type", + "target": "id=/backingFile", + "targets": [ + ["id=/backingFile", "id"], + ["name=field10", "name"], + ["css=#\\/backingFile", "css:finder"], + ["xpath=//input[@id='/backingFile']", "xpath:attributes"], + ["xpath=//div[4]/sf-form-element/div/sf-widget-chooser/custom-string/div/input", "xpath:position"] + ], + "value": "%{idp.home}/foo.txt" + }, { + "id": "203d0d3c-d866-422a-8b48-b50181db00e9", + "comment": "", + "command": "click", + "target": "css=.fa-caret-down", + "targets": [ + ["css=.fa-caret-down", "css:finder"], + ["xpath=//div[@id='/backupFileInitNextRefreshDelay-container']/div/div/button/i", "xpath:idRelative"], + ["xpath=//div/button/i", "xpath:position"] + ], + "value": "" + }, { + "id": "5fc6a348-0533-4d94-bb76-ebb891a0db8f", + "comment": "", + "command": "click", + "target": "id=/backupFileInitNextRefreshDelay__option--1", + "targets": [ + ["id=/backupFileInitNextRefreshDelay__option--1", "id"], + ["css=#\\/backupFileInitNextRefreshDelay__option--1", "css:finder"], + ["xpath=//li[@id='/backupFileInitNextRefreshDelay__option--1']", "xpath:attributes"], + ["xpath=//ul[@id='/backupFileInitNextRefreshDelay__listbox']/li[2]", "xpath:idRelative"], + ["xpath=//auto-complete/div/ul/li[2]", "xpath:position"], + ["xpath=//li[contains(.,'PT30S')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "bf041d41-5d58-4f69-8fcc-49ec79e5547d", + "comment": "", + "command": "click", + "target": "id=/requireValidMetadata.false", + "targets": [ + ["id=/requireValidMetadata.false", "id"], + ["css=#\\/requireValidMetadata\\.false", "css:finder"], + ["xpath=//input[@id='/requireValidMetadata.false']", "xpath:attributes"], + ["xpath=//div[6]/sf-form-element/div/sf-widget-chooser/boolean-radio/div/div[2]/label/input", "xpath:position"] + ], + "value": "" + }, { + "id": "fba85c75-e218-4deb-b5e1-888ff75b6a4e", + "comment": "", + "command": "click", + "target": "id=/failFastInitialization.false", + "targets": [ + ["id=/failFastInitialization.false", "id"], + ["css=#\\/failFastInitialization\\.false", "css:finder"], + ["xpath=//input[@id='/failFastInitialization.false']", "xpath:attributes"], + ["xpath=//div[7]/sf-form-element/div/sf-widget-chooser/boolean-radio/div/div[2]/label/input", "xpath:position"] + ], + "value": "" + }, { + "id": "375b8d6e-179b-4f14-8f00-d8a8cad29d7e", + "comment": "", + "command": "click", + "target": "id=/useDefaultPredicateRegistry.false", + "targets": [ + ["id=/useDefaultPredicateRegistry.false", "id"], + ["css=#\\/useDefaultPredicateRegistry\\.false", "css:finder"], + ["xpath=//input[@id='/useDefaultPredicateRegistry.false']", "xpath:attributes"], + ["xpath=//div[8]/sf-form-element/div/sf-widget-chooser/boolean-radio/div/div[2]/label/input", "xpath:position"] + ], + "value": "" + }, { + "id": "8b4bf341-62c0-491f-b775-d2faf55477bc", + "comment": "", + "command": "click", + "target": "id=/satisfyAnyPredicates.true", + "targets": [ + ["id=/satisfyAnyPredicates.true", "id"], + ["css=#\\/satisfyAnyPredicates\\.true", "css:finder"], + ["xpath=//input[@id='/satisfyAnyPredicates.true']", "xpath:attributes"], + ["xpath=//div[9]/sf-form-element/div/sf-widget-chooser/boolean-radio/div/div/label/input", "xpath:position"] + ], + "value": "" + }, { + "id": "57ca153c-4121-4531-9ebe-3dfba20fa299", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "a188bc3e-fd98-4d49-ae35-a0b78a17607c", + "comment": "", + "command": "click", + "target": "css=#\\/reloadableMetadataResolverAttributes\\/minRefreshDelay-container .btn", + "targets": [ + ["css=#\\/reloadableMetadataResolverAttributes\\/minRefreshDelay-container .btn", "css:finder"], + ["xpath=(//button[@type='button'])[2]", "xpath:attributes"], + ["xpath=//div[@id='/reloadableMetadataResolverAttributes/minRefreshDelay-container']/div/div/button", "xpath:idRelative"], + ["xpath=//div/button", "xpath:position"], + ["xpath=//button[contains(.,'Toggle Dropdown')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a159e056-c870-4e02-a7e9-4b3a60d83718", + "comment": "", + "command": "click", + "target": "id=/reloadableMetadataResolverAttributes/minRefreshDelay__option--1", + "targets": [ + ["id=/reloadableMetadataResolverAttributes/minRefreshDelay__option--1", "id"], + ["css=#\\/reloadableMetadataResolverAttributes\\/minRefreshDelay__option--1", "css:finder"], + ["xpath=//li[@id='/reloadableMetadataResolverAttributes/minRefreshDelay__option--1']", "xpath:attributes"], + ["xpath=//ul[@id='/reloadableMetadataResolverAttributes/minRefreshDelay__listbox']/li[2]", "xpath:idRelative"], + ["xpath=//auto-complete/div/ul/li[2]", "xpath:position"], + ["xpath=//li[contains(.,'PT30S')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7a72cf6a-c97a-49f6-83d0-cbe42f0fdb7d", + "comment": "", + "command": "click", + "target": "css=#\\/reloadableMetadataResolverAttributes\\/maxRefreshDelay-container .fa", + "targets": [ + ["css=#\\/reloadableMetadataResolverAttributes\\/maxRefreshDelay-container .fa", "css:finder"], + ["xpath=//div[@id='/reloadableMetadataResolverAttributes/maxRefreshDelay-container']/div/div/button/i", "xpath:idRelative"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/div/div/button/i", "xpath:position"] + ], + "value": "" + }, { + "id": "820397f5-aabb-46f5-a65a-56747ce29091", + "comment": "", + "command": "click", + "target": "id=/reloadableMetadataResolverAttributes/maxRefreshDelay__option--3", + "targets": [ + ["id=/reloadableMetadataResolverAttributes/maxRefreshDelay__option--3", "id"], + ["css=#\\/reloadableMetadataResolverAttributes\\/maxRefreshDelay__option--3", "css:finder"], + ["xpath=//li[@id='/reloadableMetadataResolverAttributes/maxRefreshDelay__option--3']", "xpath:attributes"], + ["xpath=//ul[@id='/reloadableMetadataResolverAttributes/maxRefreshDelay__listbox']/li[4]", "xpath:idRelative"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/ul/li[4]", "xpath:position"] + ], + "value": "" + }, { + "id": "b036a851-4ac9-43cb-8686-8e78ed940d72", + "comment": "", + "command": "type", + "target": "id=/reloadableMetadataResolverAttributes/refreshDelayFactor", + "targets": [ + ["id=/reloadableMetadataResolverAttributes/refreshDelayFactor", "id"], + ["name=field20", "name"], + ["css=#\\/reloadableMetadataResolverAttributes\\/refreshDelayFactor", "css:finder"], + ["xpath=//input[@id='/reloadableMetadataResolverAttributes/refreshDelayFactor']", "xpath:attributes"], + ["xpath=//custom-string/div/input", "xpath:position"] + ], + "value": "0.5" + }, { + "id": "b48d48d8-2fec-4877-85ae-2f94f15e63eb", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "232da257-962f-4a4b-8213-038ef90c96c3", + "comment": "", + "command": "click", + "target": "css=.btn-outline-secondary", + "targets": [ + ["css=.btn-outline-secondary", "css:finder"], + ["xpath=(//button[@type='button'])[2]", "xpath:attributes"], + ["xpath=//div[@id='/metadataFilters/RequiredValidUntil/maxValidityInterval-container']/div/div/button", "xpath:idRelative"], + ["xpath=//div/button", "xpath:position"], + ["xpath=//button[contains(.,'Toggle Dropdown')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "b8d999f1-0c59-4a9a-9991-91d222f52b8e", + "comment": "", + "command": "click", + "target": "id=/metadataFilters/RequiredValidUntil/maxValidityInterval__option--1", + "targets": [ + ["id=/metadataFilters/RequiredValidUntil/maxValidityInterval__option--1", "id"], + ["css=#\\/metadataFilters\\/RequiredValidUntil\\/maxValidityInterval__option--1", "css:finder"], + ["xpath=//li[@id='/metadataFilters/RequiredValidUntil/maxValidityInterval__option--1']", "xpath:attributes"], + ["xpath=//ul[@id='/metadataFilters/RequiredValidUntil/maxValidityInterval__listbox']/li[2]", "xpath:idRelative"], + ["xpath=//auto-complete/div/ul/li[2]", "xpath:position"], + ["xpath=//li[contains(.,'P14D')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8af1abb5-2c7a-4a4c-a8f7-0eb287100dde", + "comment": "", + "command": "click", + "target": "css=div:nth-child(1) > sf-form-element > .has-success .custom-control-label", + "targets": [ + ["css=div:nth-child(1) > sf-form-element > .has-success .custom-control-label", "css:finder"], + ["xpath=//div/div/label", "xpath:position"], + ["xpath=//label[contains(.,'Require Signed Root')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "323a2a02-9111-4064-8bb0-a3da34330e54", + "comment": "", + "command": "type", + "target": "id=/metadataFilters/SignatureValidation/certificateFile", + "targets": [], + "value": "%{idp.home}/foo.txt" + }, { + "id": "a125e601-f306-441d-9c8c-e97b95817b46", + "comment": "", + "command": "click", + "target": "css=.btn-success", + "targets": [ + ["css=.btn-success", "css:finder"], + ["xpath=//array-component/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Add   ')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "74d696db-3f3b-4ff3-a180-34baceb469a2", + "comment": "", + "command": "select", + "target": "id=/metadataFilters/EntityRoleWhiteList/retainedRoles/0", + "targets": [], + "value": "label=SPSSODescriptor" + }, { + "id": "532bf2e5-13fc-48d7-b01b-ff16207a554d", + "comment": "", + "command": "click", + "target": "css=option:nth-child(2)", + "targets": [ + ["css=option:nth-child(2)", "css:finder"], + ["xpath=//option[@value='1: md:SPSSODescriptor']", "xpath:attributes"], + ["xpath=//select[@id='/metadataFilters/EntityRoleWhiteList/retainedRoles/0']/option[2]", "xpath:idRelative"], + ["xpath=//option[2]", "xpath:position"], + ["xpath=//option[contains(.,'SPSSODescriptor')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "12cf80c9-594c-4c4d-bf26-aa36ba636220", + "comment": "", + "command": "click", + "target": "css=.fa-plus", + "targets": [ + ["css=.fa-plus", "css:finder"], + ["xpath=//array-component/div/div/button/i", "xpath:position"] + ], + "value": "" + }, { + "id": "6cb9854b-293b-482d-8c07-4b7c638d79cb", + "comment": "", + "command": "click", + "target": "css=#\\/metadataFilters\\/EntityRoleWhiteList\\/retainedRoles\\/1 > option:nth-child(1)", + "targets": [ + ["css=#\\/metadataFilters\\/EntityRoleWhiteList\\/retainedRoles\\/1 > option:nth-child(1)", "css:finder"], + ["xpath=(//option[@value=''])[2]", "xpath:attributes"], + ["xpath=//select[@id='/metadataFilters/EntityRoleWhiteList/retainedRoles/1']/option", "xpath:idRelative"], + ["xpath=//li[2]/div/sf-form-element/div/sf-widget-chooser/select-component/div/select/option", "xpath:position"] + ], + "value": "" + }, { + "id": "f366c86c-1420-4fb7-86c2-82c49d81208d", + "comment": "", + "command": "select", + "target": "id=/metadataFilters/EntityRoleWhiteList/retainedRoles/1", + "targets": [], + "value": "label=AttributeAuthorityDescriptor" + }, { + "id": "5dfac033-ecfd-42e8-aa6f-931d5acd4d89", + "comment": "", + "command": "click", + "target": "css=div:nth-child(2) > sf-form-element > .has-success > sf-widget-chooser > checkbox-component .custom-control-label", + "targets": [ + ["css=div:nth-child(2) > sf-form-element > .has-success > sf-widget-chooser > checkbox-component .custom-control-label", "css:finder"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/checkbox-component/div/div/div/label", "xpath:position"], + ["xpath=//label[contains(.,'Remove Roleless Entity Descriptors?')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9d5934f0-fe10-4539-9d71-80b454fc8612", + "comment": "", + "command": "click", + "target": "css=div:nth-child(3) > sf-form-element > .has-success > sf-widget-chooser > checkbox-component .custom-control-label", + "targets": [ + ["css=div:nth-child(3) > sf-form-element > .has-success > sf-widget-chooser > checkbox-component .custom-control-label", "css:finder"], + ["xpath=//div[3]/sf-form-element/div/sf-widget-chooser/checkbox-component/div/div/div/label", "xpath:position"], + ["xpath=//label[contains(.,'Remove Empty Entities Descriptors?')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "530234cd-ec70-48f2-9cc6-9e0d848c4b82", + "comment": "", + "command": "click", + "target": "css=.next", + "targets": [ + ["css=.next", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "79b96f40-2677-438a-9564-62df0ea2c116", + "comment": "", + "command": "click", + "target": "css=.custom-control-label", + "targets": [], + "value": "" + }, { + "id": "52f5680c-c63d-411e-8332-52901f12ea3b", + "comment": "", + "command": "assertText", + "target": "css=.px-3:nth-child(1) > summary-property:nth-child(2) > .mb-3 > .d-block:nth-child(2)", + "targets": [], + "value": "Test Metadata Provider" + }, { + "id": "67ff44aa-1efd-4b13-a0e9-3648a09911dd", + "comment": "", + "command": "assertText", + "target": "css=.px-3:nth-child(2) > summary-property:nth-child(2) > .mb-3 > .d-block:nth-child(2)", + "targets": [], + "value": "123" + }, { + "id": "f5197d46-41a7-4ef2-ac40-19f80c953929", + "comment": "", + "command": "click", + "target": "css=.save", + "targets": [ + ["css=.save", "css:finder"], + ["xpath=//li[3]/button", "xpath:position"] + ], + "value": "" + }, { + "id": "1067b0b4-8aff-4972-b6f5-e4479eca9150", + "comment": "", + "command": "waitForElementPresent", + "target": "css=.badge-success", + "targets": [ + ["css=.badge > span", "css:finder"], + ["xpath=//span/span", "xpath:position"] + ], + "value": "10000" + }, { + "id": "f48dd1b5-607a-485b-b1d5-03301f99b9ce", + "comment": "", + "command": "assertText", + "target": "linkText=Test Metadata Provider", + "targets": [], + "value": "Test Metadata Provider" + }, { + "id": "5eccd4e9-a451-4ec8-a9e1-1e1f8e771677", + "comment": "", + "command": "assertText", + "target": "css=td:nth-child(3)", + "targets": [], + "value": "FileBackedHttpMetadataResolver" + }, { + "id": "c768c2c1-09d4-46fe-8007-42fb4b3f4aaa", + "comment": "", + "command": "assertText", + "target": "css=td:nth-child(4)", + "targets": [], + "value": "admin" + }, { + "id": "8283ffc5-d46c-4a07-b95e-1534dfd34c02", + "comment": "", + "command": "click", + "target": "linkText=Test Metadata Provider", + "targets": [ + ["linkText=Test Metadata Provider", "linkText"], + ["css=td > a", "css:finder"], + ["xpath=//a[contains(text(),'Test Metadata Provider')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/provider/ae086029-5871-4951-bcf0-8903d7a1a1f7/configuration/options')]", "xpath:href"], + ["xpath=//td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Test Metadata Provider')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7a479ab7-f57d-426d-88ce-f11654733f45", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.save-date", + "targets": [], + "value": "10000" + }, { + "id": "fe1e9381-048e-4948-8a9a-f58d8afba258", + "comment": "", + "command": "storeText", + "target": "css=.save-date", + "targets": [], + "value": "saveDate" + }, { + "id": "a7b73d1f-87bb-4364-944a-5097f981b8c9", + "comment": "", + "command": "executeScript", + "target": "return RegExp(${dateRegex}).test(${saveDate});", + "targets": [], + "value": "isDate" + }, { + "id": "d54fd23e-e330-48d3-a1f4-31786b087425", + "comment": "", + "command": "assert", + "target": "isDate", + "targets": [], + "value": "true" + }, { + "id": "67578648-0800-4716-8c0c-27741770249a", + "comment": "", + "command": "click", + "target": "css=.mb-4:nth-child(1) .actions span", + "targets": [ + ["css=.mb-4:nth-child(1) .actions span", "css:finder"], + ["xpath=//metadata-configuration[@id='configuration']/div/section/div/div/div/button/span", "xpath:idRelative"], + ["xpath=//div/button/span", "xpath:position"], + ["xpath=//span[contains(.,'Edit')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "6a917493-6dfa-4126-ba9b-207f9c670867", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/xmlId", + "targets": [], + "value": "10000" + }, { + "id": "0aae114c-3e79-4d57-8f40-e669887a8545", + "comment": "", + "command": "pause", + "target": "2000", + "targets": [], + "value": "" + }, { + "id": "7d641e58-47ce-4d20-908c-e0002ff73cfa", + "comment": "", + "command": "type", + "target": "id=/xmlId", + "targets": [ + ["id=/xmlId", "id"], + ["name=field38", "name"], + ["css=#\\/xmlId", "css:finder"], + ["xpath=//input[@id='/xmlId']", "xpath:attributes"], + ["xpath=//custom-string/div/input", "xpath:position"] + ], + "value": "123 v2" + }, { + "id": "ebbac6ca-c3d4-486c-82f6-680842c286eb", + "comment": "", + "command": "pause", + "target": "2000", + "targets": [], + "value": "" + }, { + "id": "247b04c1-e690-42bc-ae15-dfbedb44d2e9", + "comment": "", + "command": "click", + "target": "id=/satisfyAnyPredicates.false", + "targets": [ + ["id=/satisfyAnyPredicates.false", "id"], + ["css=#\\/satisfyAnyPredicates\\.false", "css:finder"], + ["xpath=//input[@id='/satisfyAnyPredicates.false']", "xpath:attributes"], + ["xpath=//div[10]/sf-form-element/div/sf-widget-chooser/boolean-radio/div/div[2]/label/input", "xpath:position"] + ], + "value": "" + }, { + "id": "6806c391-11a9-4f40-8a73-d57ab3304c11", + "comment": "", + "command": "pause", + "target": "2000", + "targets": [], + "value": "" + }, { + "id": "5aacc6b8-b509-4405-8755-c60fa3619e67", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=//div[2]/button", "xpath:position"], + ["xpath=//button[contains(.,'Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "7e42b8b2-cc31-4fb5-bcf8-77d8068e2e04", + "comment": "", + "command": "pause", + "target": "2000", + "targets": [], + "value": "" + }, { + "id": "cf005a45-74ae-4f7a-a53c-ed59d63f7114", + "comment": "", + "command": "click", + "target": "linkText=Test Metadata Provider", + "targets": [ + ["linkText=Test Metadata Provider", "linkText"], + ["css=td > a", "css:finder"], + ["xpath=//a[contains(text(),'Test Metadata Provider')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/provider/ae086029-5871-4951-bcf0-8903d7a1a1f7/configuration/options')]", "xpath:href"], + ["xpath=//td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Test Metadata Provider')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "8e00ca0d-61e3-413d-8422-a09232049bab", + "comment": "", + "command": "pause", + "target": "2000", + "targets": [], + "value": "" + }, { + "id": "ea880e6a-498a-427a-bc08-8058137d62e0", + "comment": "", + "command": "click", + "target": "css=.btn-link:nth-child(1)", + "targets": [ + ["css=.btn-link:nth-child(1) > translate-i18n", "css:finder"], + ["xpath=//div[@id='navigation']/div/a/translate-i18n", "xpath:idRelative"], + ["xpath=//div/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Version History')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "62211421-e36c-426c-80ef-be10ff259d87", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.btn-text", + "targets": [ + ["css=.btn-text", "css:finder"], + ["xpath=//td[4]/button", "xpath:position"], + ["xpath=//button[contains(.,'  Restore')]", "xpath:innerText"] + ], + "value": "10000" + }, { + "id": "271939a6-6196-4c14-aa13-e6c31e0373c2", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "c223e329-733c-41eb-9e85-c6f69a840179", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(1) .custom-control-label", + "targets": [ + ["css=tr:nth-child(1) .custom-control-label", "css:finder"], + ["xpath=//label", "xpath:position"], + ["xpath=//label[contains(.,'Check to select')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9b764399-76cc-44e7-8d72-5a3383387a5f", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(2) .custom-control-label", + "targets": [ + ["css=tr:nth-child(2) .custom-control-label", "css:finder"], + ["xpath=//tr[2]/td/div/label", "xpath:position"] + ], + "value": "" + }, { + "id": "32ef784f-ccf0-4fd7-afff-40f0ba877dad", + "comment": "", + "command": "click", + "target": "css=.btn-primary", + "targets": [ + ["css=.btn-primary > translate-i18n", "css:finder"], + ["xpath=//history-list/button/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Compare Selected')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ce328b6a-f6ee-45e9-975c-5a5608f373dc", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.d-block > primitive-property:nth-child(2) .d-block:nth-child(2)", + "targets": [], + "value": "10000" + }, { + "id": "68103f0e-e3f1-419b-903d-5d8c30bc6700", + "comment": "", + "command": "assertText", + "target": "css=.d-block > primitive-property:nth-child(4) .d-block:nth-child(2)", + "targets": [], + "value": "123 v2" + }, { + "id": "a13198b9-7827-47e2-ade3-143b981d34ee", + "comment": "", + "command": "assertText", + "target": "css=.d-block > primitive-property:nth-child(4) .d-block:nth-child(3)", + "targets": [], + "value": "123" + }, { + "id": "3d83741c-299e-4fcb-9ce6-4b7291c423a4", + "comment": "", + "command": "assertText", + "target": "css=.d-block > primitive-property:nth-child(12) .d-block:nth-child(2)", + "targets": [], + "value": "false" + }, { + "id": "190cc157-d427-4046-aff2-180392395ad3", + "comment": "", + "command": "assertText", + "target": "css=.d-block > primitive-property:nth-child(12) .d-block:nth-child(3)", + "targets": [], + "value": "true" + }, { + "id": "f6897c4f-763f-4360-95a2-1d144455fa17", + "comment": "", + "command": "click", + "target": "css=.breadcrumb-item > a", + "targets": [ + ["css=.breadcrumb-item > a", "css:finder"], + ["xpath=//a[contains(text(),'Dashboard')]", "xpath:link"], + ["xpath=(//a[contains(@href, '/dashboard')])[2]", "xpath:href"], + ["xpath=//ol/li/a", "xpath:position"] + ], + "value": "" + }, { + "id": "41c1d29e-9eaa-41d3-979b-46601fd7a178", + "comment": "", + "command": "click", + "target": "linkText=Metadata Providers", + "targets": [ + ["linkText=Metadata Providers", "linkText"], + ["css=.nav > .nav-item:nth-child(2) > .nav-link", "css:finder"], + ["xpath=//a[contains(text(),'Metadata Providers')]", "xpath:link"], + ["xpath=//a[contains(@href, '/dashboard/metadata/manager/providers')]", "xpath:href"], + ["xpath=//dashboard-page/div/ul/li[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Metadata Providers')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "5dd3952e-d716-4d63-8a08-23be4983da23", + "comment": "", + "command": "click", + "target": "linkText=Test Metadata Provider", + "targets": [ + ["linkText=Test Metadata Provider", "linkText"], + ["css=td > a", "css:finder"], + ["xpath=//a[contains(text(),'Test Metadata Provider')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/provider/eb0ee617-33e2-4a31-83a5-7c42515c3b4f/configuration/options')]", "xpath:href"], + ["xpath=//td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Test Metadata Provider')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "c9341f6f-4d13-4378-bb5c-0079e7535008", + "comment": "", + "command": "click", + "target": "css=.mb-4:nth-child(4) .actions span", + "targets": [ + ["css=.mb-4:nth-child(4) .actions span", "css:finder"], + ["xpath=//metadata-configuration[@id='configuration']/div/section[4]/div/div/div/button/span", "xpath:idRelative"], + ["xpath=//section[4]/div/div/div/button/span", "xpath:position"] + ], + "value": "" + }, { + "id": "78967fb5-8f61-46ce-9c14-9b6ceb12b03a", + "comment": "", + "command": "click", + "target": "css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", + "targets": [ + ["css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", "css:finder"], + ["xpath=(//button[@type='button'])[2]", "xpath:attributes"], + ["xpath=//div[@id='/httpMetadataResolverAttributes/connectionRequestTimeout-container']/div/div/button", "xpath:idRelative"], + ["xpath=//auto-complete/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Toggle Dropdown')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "1cde012c-d521-4fd5-a7d5-7a680bba0e7b", + "comment": "", + "command": "click", + "target": "css=.slider", + "targets": [ + ["css=.slider", "css:finder"], + ["xpath=//toggle-switch[@id='toggle']/label/span", "xpath:idRelative"], + ["xpath=//label/span", "xpath:position"] + ], + "value": "" + }, { + "id": "d00ecf98-7425-467c-acbb-3b39918e3462", + "comment": "", + "command": "click", + "target": "css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", + "targets": [ + ["css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout-container .btn", "css:finder"], + ["xpath=(//button[@type='button'])[2]", "xpath:attributes"], + ["xpath=//div[@id='/httpMetadataResolverAttributes/connectionRequestTimeout-container']/div/div/button", "xpath:idRelative"], + ["xpath=//auto-complete/div/div/div/button", "xpath:position"], + ["xpath=//button[contains(.,'Toggle Dropdown')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "6e01f905-fd32-45a5-9517-9dd12191f7ae", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/httpMetadataResolverAttributes/connectionRequestTimeout__option--1", + "targets": [], + "value": "10000" + }, { + "id": "8ba62572-354d-47f4-bb72-f9309c1cb201", + "comment": "", + "command": "click", + "target": "id=/httpMetadataResolverAttributes/connectionRequestTimeout__option--1", + "targets": [ + ["id=/httpMetadataResolverAttributes/connectionRequestTimeout__option--1", "id"], + ["css=#\\/httpMetadataResolverAttributes\\/connectionRequestTimeout__option--1", "css:finder"], + ["xpath=//li[@id='/httpMetadataResolverAttributes/connectionRequestTimeout__option--1']", "xpath:attributes"], + ["xpath=//ul[@id='/httpMetadataResolverAttributes/connectionRequestTimeout__listbox']/li[2]", "xpath:idRelative"], + ["xpath=//auto-complete/div/ul/li[2]", "xpath:position"], + ["xpath=//li[contains(.,'PT30S')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "d7406190-0bb0-4df8-9c0b-7e393952b6a2", + "comment": "", + "command": "click", + "target": "css=#\\/httpMetadataResolverAttributes\\/connectionTimeout-container .btn", + "targets": [ + ["css=#\\/httpMetadataResolverAttributes\\/connectionTimeout-container .btn", "css:finder"], + ["xpath=(//button[@type='button'])[3]", "xpath:attributes"], + ["xpath=//div[@id='/httpMetadataResolverAttributes/connectionTimeout-container']/div/div/button", "xpath:idRelative"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "01d5f751-6964-4fd8-a0de-36fd79d7be99", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/httpMetadataResolverAttributes/connectionTimeout__option--2", + "targets": [], + "value": "10000" + }, { + "id": "337ac160-7990-425f-83da-2788d8a0985e", + "comment": "", + "command": "click", + "target": "id=/httpMetadataResolverAttributes/connectionTimeout__option--2", + "targets": [ + ["id=/httpMetadataResolverAttributes/connectionTimeout__option--2", "id"], + ["css=#\\/httpMetadataResolverAttributes\\/connectionTimeout__option--2", "css:finder"], + ["xpath=//li[@id='/httpMetadataResolverAttributes/connectionTimeout__option--2']", "xpath:attributes"], + ["xpath=//ul[@id='/httpMetadataResolverAttributes/connectionTimeout__listbox']/li[3]", "xpath:idRelative"], + ["xpath=//div[2]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/ul/li[3]", "xpath:position"] + ], + "value": "" + }, { + "id": "19182110-0f86-4601-ae12-0b90967ef68a", + "comment": "", + "command": "click", + "target": "css=#\\/httpMetadataResolverAttributes\\/socketTimeout-container .btn", + "targets": [ + ["css=#\\/httpMetadataResolverAttributes\\/socketTimeout-container .btn", "css:finder"], + ["xpath=(//button[@type='button'])[4]", "xpath:attributes"], + ["xpath=//div[@id='/httpMetadataResolverAttributes/socketTimeout-container']/div/div/button", "xpath:idRelative"], + ["xpath=//div[3]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/div/div/button", "xpath:position"] + ], + "value": "" + }, { + "id": "99c7ec5a-ad8c-4970-b97f-27997098c0d6", + "comment": "", + "command": "waitForElementVisible", + "target": "id=/httpMetadataResolverAttributes/socketTimeout__option--3", + "targets": [], + "value": "10000" + }, { + "id": "34693225-4754-4b27-92ee-3e37304a8cd7", + "comment": "", + "command": "click", + "target": "id=/httpMetadataResolverAttributes/socketTimeout__option--3", + "targets": [ + ["id=/httpMetadataResolverAttributes/socketTimeout__option--3", "id"], + ["css=#\\/httpMetadataResolverAttributes\\/socketTimeout__option--3", "css:finder"], + ["xpath=//li[@id='/httpMetadataResolverAttributes/socketTimeout__option--3']", "xpath:attributes"], + ["xpath=//ul[@id='/httpMetadataResolverAttributes/socketTimeout__listbox']/li[4]", "xpath:idRelative"], + ["xpath=//div[3]/sf-form-element/div/sf-widget-chooser/datalist-component/div/auto-complete/div/ul/li[4]", "xpath:position"] + ], + "value": "" + }, { + "id": "d9a9dcb4-bac1-4f5a-a822-047bd2941df0", + "comment": "", + "command": "click", + "target": "css=.btn-info", + "targets": [ + ["css=.btn-info", "css:finder"], + ["xpath=//div[2]/button", "xpath:position"], + ["xpath=//button[contains(.,'Save')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "4e2831c6-d1ba-409d-a0cc-7a25dad75421", + "comment": "", + "command": "waitForElementVisible", + "target": "linkText=Test Metadata Provider", + "targets": [], + "value": "10000" + }, { + "id": "8868c054-2e6a-403e-ba2b-499a56730d71", + "comment": "", + "command": "click", + "target": "linkText=Test Metadata Provider", + "targets": [ + ["linkText=Test Metadata Provider", "linkText"], + ["css=td > a", "css:finder"], + ["xpath=//a[contains(text(),'Test Metadata Provider')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/provider/eb0ee617-33e2-4a31-83a5-7c42515c3b4f/configuration/options')]", "xpath:href"], + ["xpath=//td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Test Metadata Provider')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "0092cd5c-a885-4a48-a233-b3af447b02bc", + "comment": "", + "command": "click", + "target": "css=.btn-link:nth-child(1)", + "targets": [ + ["css=.btn-link:nth-child(1) > translate-i18n", "css:finder"], + ["xpath=//div[@id='navigation']/div/a/translate-i18n", "xpath:idRelative"], + ["xpath=//div/a/translate-i18n", "xpath:position"], + ["xpath=//translate-i18n[contains(.,'Version History')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "ca6537f7-73d1-4f02-ba06-c24f66c569e3", + "comment": "", + "command": "waitForElementVisible", + "target": "css=tr:nth-child(1) a", + "targets": [ + ["css=tr:nth-child(1) a", "css:finder"], + ["xpath=//a[contains(@href, '/metadata/provider/a9294f9e-2e19-4e87-9157-11d86a32f2f9/configuration/options?version=64')]", "xpath:href"], + ["xpath=//td[2]/a", "xpath:position"] + ], + "value": "10000" + }, { + "id": "6620688a-039a-4969-92be-b1fcfc8a4161", + "comment": "", + "command": "storeText", + "target": "css=tr:nth-child(1) a", + "targets": [ + ["linkText=Aug 14, 2019 22:52:11", "linkText"], + ["css=tr:nth-child(2) a", "css:finder"], + ["xpath=//a[contains(text(),'Aug 14, 2019 22:52:11')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/provider/1552c0d4-29ea-4dd2-9296-9bf0280157fa/configuration/options?version=33')]", "xpath:href"], + ["xpath=//tr[2]/td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Aug 14, 2019 22:52:11 ')]", "xpath:innerText"] + ], + "value": "saveDate" + }, { + "id": "910d8bf9-4875-4946-9ab8-0d3a9b13f020", + "comment": "", + "command": "executeScript", + "target": "return RegExp(${dateRegex}).test(${saveDate});", + "targets": [], + "value": "isDate" + }, { + "id": "18458e4b-e414-4125-aa4d-fd27848d3c40", + "comment": "", + "command": "assert", + "target": "isDate", + "targets": [], + "value": "true" + }, { + "id": "48adfc53-ed95-4e59-aa57-45eb57128154", + "comment": "", + "command": "storeText", + "target": "css=tr:nth-child(2) a", + "targets": [ + ["linkText=Aug 14, 2019 22:51:54", "linkText"], + ["css=tr:nth-child(3) a", "css:finder"], + ["xpath=//a[contains(text(),'Aug 14, 2019 22:51:54')]", "xpath:link"], + ["xpath=//a[contains(@href, '/metadata/provider/1552c0d4-29ea-4dd2-9296-9bf0280157fa/configuration/options?version=32')]", "xpath:href"], + ["xpath=//tr[3]/td[2]/a", "xpath:position"], + ["xpath=//a[contains(.,'Aug 14, 2019 22:51:54 ')]", "xpath:innerText"] + ], + "value": "saveDate" + }, { + "id": "a370624e-a6d6-43d7-a74a-eeb8c577fc06", + "comment": "", + "command": "executeScript", + "target": "return RegExp(${dateRegex}).test(${saveDate});", + "targets": [], + "value": "isDate" + }, { + "id": "21e88ab8-7f11-42ae-8db8-ccc21116c303", + "comment": "", + "command": "assert", + "target": "isDate", + "targets": [], + "value": "true" + }, { + "id": "2a299cc4-7b22-42e6-89cd-4ae0aef8bb27", + "comment": "", + "command": "storeText", + "target": "css=tr:nth-child(3) a", + "targets": [ + ["css=tr:nth-child(3) > td:nth-child(3)", "css:finder"], + ["xpath=//tr[3]/td[3]", "xpath:position"], + ["xpath=//td[contains(.,'Aug 08, 2019 16:09:52')]", "xpath:innerText"] + ], + "value": "saveDate" + }, { + "id": "4b305857-0369-4fad-821c-c944e9801395", + "comment": "", + "command": "executeScript", + "target": "return RegExp(${dateRegex}).test(${saveDate});", + "targets": [], + "value": "isDate" + }, { + "id": "3fd48668-3df2-4264-85c9-01dac26acaee", + "comment": "", + "command": "assert", + "target": "isDate", + "targets": [], + "value": "true" + }, { + "id": "48fc4781-3313-4f56-8546-00e8210d9641", + "comment": "", + "command": "pause", + "target": "5000", + "targets": [], + "value": "" + }, { + "id": "2cfe222d-a506-4f2b-8840-4b4a76cf2bfb", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(1) .custom-control-label", + "targets": [ + ["css=tr:nth-child(1) .custom-control-label", "css:finder"], + ["xpath=//label", "xpath:position"], + ["xpath=//label[contains(.,'Check to select')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "a10e3e37-28f1-403f-b572-8b4020de7904", + "comment": "", + "command": "click", + "target": "css=tr:nth-child(3) .custom-control-label", + "targets": [ + ["css=tr:nth-child(2) .custom-control-label", "css:finder"], + ["xpath=//tr[2]/td/div/label", "xpath:position"] + ], + "value": "" + }, { + "id": "d487ae82-707d-4991-8914-89cf181b656e", + "comment": "", + "command": "click", + "target": "css=.btn-primary", + "targets": [ + ["css=.btn-primary", "css:finder"], + ["xpath=//history-list/button", "xpath:position"], + ["xpath=//button[contains(.,'Compare Selected(2)')]", "xpath:innerText"] + ], + "value": "" + }, { + "id": "9f1380c3-2b99-4b7d-90b7-f20d4fe431d3", + "comment": "", + "command": "waitForElementVisible", + "target": "css=.mb-4:nth-child(4) primitive-property:nth-child(2) .d-block:nth-child(2)", + "targets": [], + "value": "10000" + }, { + "id": "8a2c6435-d77b-4c87-8e0e-e1ae6d4629b9", + "comment": "", + "command": "assertText", + "target": "css=.mb-4:nth-child(4) primitive-property:nth-child(2) .d-block:nth-child(2)", + "targets": [], + "value": "PT30S" + }, { + "id": "0687fe3f-c1af-4a5a-9708-09b7b92734bc", + "comment": "", + "command": "assertText", + "target": "css=.mb-4:nth-child(4) primitive-property:nth-child(3) .d-block:nth-child(2)", + "targets": [], + "value": "PT1M" + }, { + "id": "a007794f-ab91-47b8-b470-e4294e47a2a7", + "comment": "", + "command": "assertText", + "target": "css=object-property:nth-child(1) > primitive-property:nth-child(4) .d-block:nth-child(2)", + "targets": [], + "value": "PT10M" + }, { + "id": "5279bf64-46c1-4376-a527-e19e217b42fa", + "comment": "", + "command": "assertText", + "target": "css=object-property:nth-child(1) > primitive-property:nth-child(5) .d-block:nth-child(2)", + "targets": [], + "value": "false" + }, { + "id": "cc2f6596-d135-48ef-abab-8f2c4bf44a2c", + "comment": "", + "command": "storeText", + "target": "css=.mb-4:nth-child(1) strong:nth-child(2) > span", + "targets": [ + ["css=.mb-4:nth-child(1) strong:nth-child(2) > span", "css:finder"], + ["xpath=//strong[2]/span", "xpath:position"], + ["xpath=//span[contains(.,'Aug 08, 2019 16:10:01')]", "xpath:innerText"] + ], + "value": "leftDate" + }, { + "id": "c1fda79e-9fa9-4969-92f5-83f9f54b9d3d", + "comment": "", + "command": "executeScript", + "target": "return RegExp(${dateRegex}).test(${leftDate});", + "targets": [], + "value": "leftDateIsDate" + }, { + "id": "30e8b9fb-254d-462e-9039-6b378ff4d245", + "comment": "", + "command": "assert", + "target": "leftDateIsDate", + "targets": [], + "value": "true" + }, { + "id": "a55513b6-d1dd-4036-9b99-4d03e845d65a", + "comment": "", + "command": "storeText", + "target": "css=.mb-4:nth-child(1) strong:nth-child(3) > span", + "targets": [ + ["css=.mb-4:nth-child(1) strong:nth-child(3) > span", "css:finder"], + ["xpath=//strong[3]/span", "xpath:position"], + ["xpath=//span[contains(.,'Aug 08, 2019 16:09:55')]", "xpath:innerText"] + ], + "value": "rightDate" + }, { + "id": "dd3a52a4-de8b-4c25-a6e7-81b7ee9f8149", + "comment": "", + "command": "executeScript", + "target": "return RegExp(${dateRegex}).test(${rightDate});", + "targets": [], + "value": "rightDateIsDate" + }, { + "id": "d973102f-964b-4021-93f4-44adf165b33e", + "comment": "", + "command": "assert", + "target": "rightDateIsDate", + "targets": [], + "value": "true" + }] + }], + "suites": [{ + "id": "894bbaf7-9978-4d30-b4e3-3c4263e084aa", + "name": "Default Suite", + "persistSession": false, + "parallel": false, + "timeout": 300, + "tests": ["1e7a4ca4-b2e6-4e5a-8e38-823ae8a1e20d"] + }], + "urls": ["http://localhost:10101/"], + "plugins": [] +} \ No newline at end of file diff --git a/backend/src/main/resources/application.properties b/backend/src/main/resources/application.properties index 559a6c082..909b2943a 100644 --- a/backend/src/main/resources/application.properties +++ b/backend/src/main/resources/application.properties @@ -20,6 +20,7 @@ spring.jpa.database-platform=org.hibernate.dialect.H2Dialect spring.h2.console.enabled=true # spring.jackson.default-property-inclusion=non_absent +spring.jackson.default-property-inclusion=NON_NULL # Database Configuration PostgreSQL #spring.datasource.url=jdbc:postgresql://localhost:5432/shibui diff --git a/backend/src/main/resources/i18n/messages.properties b/backend/src/main/resources/i18n/messages.properties index f82153ce6..673a47728 100644 --- a/backend/src/main/resources/i18n/messages.properties +++ b/backend/src/main/resources/i18n/messages.properties @@ -55,10 +55,12 @@ action.xml=XML action.manage=Manage action.close=Close action.back-to-top=Back to Top +action.restore=Restore value.enabled=Enabled value.disabled=Disabled value.current=Current +value.not-current=Not Current value.none=None value.file=File value.memory=Memory @@ -416,6 +418,7 @@ label.check-to-select=Check to select label.current=Current label.restore=Restore label.compare-selected=Compare Selected +label.restore-version=Restore Version ({ date }) label.saved=Saved label.by=By @@ -471,6 +474,9 @@ message.database-constraint=There was a database constraint problem processing t message.no-filters=No Filters message.no-filters-added=No filters have been added to this Metadata Provider +message.create-new-version-from-version=Create New Version from Previous Settings +message.restoring-this-version-will-copy=Restoring this version will copy the Version ({ date }) configuration and create a new Version from the selected version settings. You can then edit the configuration before saving the new version. + tooltip.entity-id=Entity ID tooltip.service-provider-name=Service Provider Name (Dashboard Display Only) tooltip.force-authn=Disallows use (or reuse) of authentication results and login flows that don\u0027t provide a real-time proof of user presence in the login process diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy index af758f131..b9789201f 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests.groovy @@ -7,6 +7,7 @@ import org.springframework.boot.test.context.SpringBootTest import org.springframework.boot.test.context.TestConfiguration import org.springframework.boot.test.web.client.TestRestTemplate import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Profile import org.springframework.core.io.ResourceLoader import org.springframework.test.context.ActiveProfiles import spock.lang.Specification @@ -23,7 +24,7 @@ import static edu.internet2.tier.shibboleth.admin.ui.jsonschema.JsonSchemaResour * @author Dmitriy Kopylenko */ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@ActiveProfiles("no-auth") +@ActiveProfiles(["no-auth", "badjson"]) class BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests extends Specification { @Autowired @@ -42,6 +43,7 @@ class BadJSONMetadataSourcesUiDefinitionControllerIntegrationTests extends Speci } @TestConfiguration + @Profile('badjson') static class Config { @Bean JsonSchemaResourceLocationRegistry jsonSchemaResourceLocationRegistry(ResourceLoader resourceLoader, diff --git a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerIntegrationTests.groovy b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerIntegrationTests.groovy index 8bf12484a..d8d9e7afb 100644 --- a/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerIntegrationTests.groovy +++ b/backend/src/test/groovy/edu/internet2/tier/shibboleth/admin/ui/controller/EntitiesControllerIntegrationTests.groovy @@ -42,25 +42,16 @@ class EntitiesControllerIntegrationTests extends Specification { def "GET /api/entities returns the proper json"() { given: def expectedBody = ''' - { - "id":null, - "serviceProviderName":null, - "entityId":"http://test.scaldingspoon.org/test1", - "organization":null, - "contacts":null, - "mdui":null, + { + "entityId":"http://test.scaldingspoon.org/test1", "serviceProviderSsoDescriptor": { "protocolSupportEnum":"SAML 2", "nameIdFormats":["urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"] - }, - "logoutEndpoints":null, - "securityInfo":null, + }, "assertionConsumerServices":[ {"locationUrl":"https://test.scaldingspoon.org/test1/acs","binding":"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST","makeDefault":false} ], - "serviceEnabled":false, - "createdDate":null, - "modifiedDate":null, + "serviceEnabled":false, "relyingPartyOverrides":{}, "attributeRelease":["givenName","employeeNumber"] } diff --git a/ui/src/app/metadata/configuration/action/configuration.action.ts b/ui/src/app/metadata/configuration/action/configuration.action.ts index 8a12d47c8..b1eb9c00a 100644 --- a/ui/src/app/metadata/configuration/action/configuration.action.ts +++ b/ui/src/app/metadata/configuration/action/configuration.action.ts @@ -71,13 +71,13 @@ export class SetMetadataModel implements Action { constructor(public payload: Metadata) { } } -export class SetDefinition implements Action { +export class SetConfigurationDefinition implements Action { readonly type = ConfigurationActionTypes.SET_DEFINITION; constructor(public payload: Wizard) { } } -export class SetSchema implements Action { +export class SetConfigurationSchema implements Action { readonly type = ConfigurationActionTypes.SET_SCHEMA; constructor(public payload: Schema) { } @@ -105,8 +105,8 @@ export type ConfigurationActionsUnion = | LoadXmlSuccess | LoadXmlError | SetMetadata - | SetDefinition - | SetSchema + | SetConfigurationDefinition + | SetConfigurationSchema | SetXml | DownloadXml | ClearConfiguration; diff --git a/ui/src/app/metadata/configuration/action/restore.action.ts b/ui/src/app/metadata/configuration/action/restore.action.ts index 48861c35e..978e9eee4 100644 --- a/ui/src/app/metadata/configuration/action/restore.action.ts +++ b/ui/src/app/metadata/configuration/action/restore.action.ts @@ -1,36 +1,70 @@ import { Action } from '@ngrx/store'; import { Metadata } from '../../domain/domain.type'; +import { VersionRequest } from '../model/request'; export enum RestoreActionTypes { - SELECT_VERSION_SUCCESS = '[Restore Version] Select Version Success', - SELECT_VERSION_ERROR = '[Restore Version] Select Version Error', - SELECT_VERSION_REQUEST = '[Restore Version] Select Version Request', - CLEAR_VERSION = '[Restore Version] Clear Versions' -} + RESTORE_VERSION_REQUEST = '[Restore Version] Restore Version Request', + RESTORE_VERSION_SUCCESS = '[Restore Version] Restore Version Success', + RESTORE_VERSION_ERROR = '[Restore Version] Restore Version Error', + + UPDATE_RESTORATION_REQUEST = '[Restore Version] Update Changes Request', + UPDATE_RESTORATION_SUCCESS = '[Restore Version] Update Changes Success', -export class SelectVersionRestoreRequest implements Action { - readonly type = RestoreActionTypes.SELECT_VERSION_REQUEST; + UPDATE_STATUS = '[Restore Version] Update Restore Form Status', + SET_SAVING_STATUS = '[Restore Version] Set Saving Status', - constructor(public payload: { type: string, id: string, version: string }) { } + CLEAR_VERSION = '[Restore Version] Clear Versions', + CANCEL_RESTORE = '[Restore Version] Cancel Restore' } -export class SelectVersionRestoreSuccess implements Action { - readonly type = RestoreActionTypes.SELECT_VERSION_SUCCESS; +export class RestoreVersionRequest implements Action { + readonly type = RestoreActionTypes.RESTORE_VERSION_REQUEST; + constructor() { } +} - constructor(public payload: Metadata) { } +export class RestoreVersionSuccess implements Action { + readonly type = RestoreActionTypes.RESTORE_VERSION_SUCCESS; + constructor(public payload: { id: string, type: string, model: Metadata }) { } } -export class SelectVersionRestoreError implements Action { - readonly type = RestoreActionTypes.SELECT_VERSION_ERROR; +export class RestoreVersionError implements Action { + readonly type = RestoreActionTypes.RESTORE_VERSION_ERROR; constructor(public payload: any) { } } -export class ClearVersionRestore implements Action { - readonly type = RestoreActionTypes.CLEAR_VERSION; +export class UpdateRestorationChangesRequest implements Action { + readonly type = RestoreActionTypes.UPDATE_RESTORATION_REQUEST; + constructor(public payload: Partial) { } +} + +export class UpdateRestorationChangesSuccess implements Action { + readonly type = RestoreActionTypes.UPDATE_RESTORATION_SUCCESS; + constructor(public payload: Partial) { } +} + +export class UpdateRestoreFormStatus implements Action { + readonly type = RestoreActionTypes.UPDATE_STATUS; + + constructor(public payload: { [key: string]: string }) { } +} + +export class SetSavingStatus implements Action { + readonly type = RestoreActionTypes.SET_SAVING_STATUS; + + constructor(public payload: boolean) { } +} + +export class CancelRestore implements Action { + readonly type = RestoreActionTypes.CANCEL_RESTORE; + constructor() { } } export type RestoreActionsUnion = - | SelectVersionRestoreRequest - | SelectVersionRestoreError - | SelectVersionRestoreSuccess - | ClearVersionRestore; + | RestoreVersionRequest + | RestoreVersionSuccess + | RestoreVersionError + | UpdateRestorationChangesRequest + | UpdateRestorationChangesSuccess + | UpdateRestoreFormStatus + | SetSavingStatus + | CancelRestore; diff --git a/ui/src/app/metadata/configuration/action/version.action.ts b/ui/src/app/metadata/configuration/action/version.action.ts new file mode 100644 index 000000000..0379a240b --- /dev/null +++ b/ui/src/app/metadata/configuration/action/version.action.ts @@ -0,0 +1,40 @@ +import { Action } from '@ngrx/store'; +import { Metadata } from '../../domain/domain.type'; +import { VersionRequest } from '../model/request'; + +export enum VersionActionTypes { + SELECT_VERSION_SUCCESS = '[Version] Select Version Success', + SELECT_VERSION_ERROR = '[Version] Select Version Error', + SELECT_VERSION_REQUEST = '[Version] Select Version Request', + + CLEAR_VERSION = '[Version] Clear Versions' +} + +export class SelectVersionRequest implements Action { + readonly type = VersionActionTypes.SELECT_VERSION_REQUEST; + + constructor(public payload: VersionRequest) { } +} + +export class SelectVersionSuccess implements Action { + readonly type = VersionActionTypes.SELECT_VERSION_SUCCESS; + + constructor(public payload: Metadata) { } +} +export class SelectVersionError implements Action { + readonly type = VersionActionTypes.SELECT_VERSION_ERROR; + + constructor(public payload: any) { } +} + +export class ClearVersion implements Action { + readonly type = VersionActionTypes.CLEAR_VERSION; + + constructor() { } +} + +export type VersionActionsUnion = + | SelectVersionRequest + | SelectVersionError + | SelectVersionSuccess + | ClearVersion; diff --git a/ui/src/app/metadata/configuration/component/editor.component.html b/ui/src/app/metadata/configuration/component/editor.component.html new file mode 100644 index 000000000..fd71771aa --- /dev/null +++ b/ui/src/app/metadata/configuration/component/editor.component.html @@ -0,0 +1,14 @@ +
+ + + {{ lock.value ? 'Locked' : 'Unlocked' }} + + For Advanced Knowledge Only +
+ \ No newline at end of file diff --git a/ui/src/app/metadata/configuration/component/editor.component.ts b/ui/src/app/metadata/configuration/component/editor.component.ts new file mode 100644 index 000000000..59f3ef375 --- /dev/null +++ b/ui/src/app/metadata/configuration/component/editor.component.ts @@ -0,0 +1,29 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { FormControl } from '@angular/forms'; +import { Metadata } from '../../domain/domain.type'; + + +@Component({ + selector: 'metadata-editor', + templateUrl: './editor.component.html', + styleUrls: [] +}) +export class MetadataEditorComponent { + + @Input() schema: any; + @Input() bindings: any; + @Input() validators: { [key: string]: any }; + @Input() model: Metadata; + @Input() lockable: boolean; + + @Output() change: EventEmitter = new EventEmitter(); + @Output() status: EventEmitter = new EventEmitter(); + @Output() onLockChange: EventEmitter = new EventEmitter(); + + lock: FormControl = new FormControl(true); + + constructor() { + this.lock.valueChanges.subscribe(locked => this.onLockChange.emit(locked)); + } +} + diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html index b8df62a11..cf1cfe3be 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.html @@ -1,6 +1,6 @@
{{ index + 1 }} -
+

-
+
diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts index ede42a55a..9e5cb7630 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list-item.component.ts @@ -16,6 +16,7 @@ export class FilterConfigurationListItemComponent implements OnChanges { @Input() index: number; @Input() isFirst: boolean; @Input() isLast: boolean; + @Input() editable: boolean; @Output() onUpdateOrderUp: EventEmitter = new EventEmitter(); @Output() onUpdateOrderDown: EventEmitter = new EventEmitter(); diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html index c49a7738c..03d89d651 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.html @@ -6,6 +6,7 @@ [index]="i" [isFirst]="isFirst" [isLast]="isLast" + [editable]="editable" (onUpdateOrderDown)="onUpdateOrderDown.emit($event)" (onUpdateOrderUp)="onUpdateOrderUp.emit($event)" (onRemove)="onRemove.emit($event)"> diff --git a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts index 5208a7f4c..17f377480 100644 --- a/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts +++ b/ui/src/app/metadata/configuration/component/filter-configuration-list.component.ts @@ -1,8 +1,10 @@ -import { Component } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { FilterListComponent } from '../../filter/component/filter-list.component'; @Component({ selector: 'filter-configuration-list', templateUrl: './filter-configuration-list.component.html' }) -export class FilterConfigurationListComponent extends FilterListComponent { } +export class FilterConfigurationListComponent extends FilterListComponent { + @Input() editable = true; +} diff --git a/ui/src/app/metadata/configuration/component/history-list.component.html b/ui/src/app/metadata/configuration/component/history-list.component.html index ff4599b91..668308311 100644 --- a/ui/src/app/metadata/configuration/component/history-list.component.html +++ b/ui/src/app/metadata/configuration/component/history-list.component.html @@ -21,20 +21,18 @@
- - - {{ version.date | date:DATE_FORMAT }}  - - (Current) - - + + {{ version.date | date:DATE_FORMAT }} (Current) + + + {{ version.date | date:DATE_FORMAT }} {{ version.creator }} diff --git a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html index f5ab2814b..f4826cfe6 100644 --- a/ui/src/app/metadata/configuration/component/metadata-configuration.component.html +++ b/ui/src/app/metadata/configuration/component/metadata-configuration.component.html @@ -1,8 +1,7 @@
-
+

diff --git a/ui/src/app/metadata/configuration/component/metadata-header.component.html b/ui/src/app/metadata/configuration/component/metadata-header.component.html index 9041ae00e..5278ed3bd 100644 --- a/ui/src/app/metadata/configuration/component/metadata-header.component.html +++ b/ui/src/app/metadata/configuration/component/metadata-header.component.html @@ -2,16 +2,17 @@
Saved:  - {{ version.date | date:DATE_FORMAT }} + {{ version.modifiedDate | date:DATE_FORMAT }}
By:  - {{ version.creator }} + {{ version.createdBy }}

Enabled Disabled   Current + Not Current

\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/component/metadata-header.component.spec.ts b/ui/src/app/metadata/configuration/component/metadata-header.component.spec.ts index e8db42c36..f3cfd0d45 100644 --- a/ui/src/app/metadata/configuration/component/metadata-header.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/metadata-header.component.spec.ts @@ -9,7 +9,6 @@ import { MetadataHeaderComponent } from './metadata-header.component'; ` @@ -25,7 +24,6 @@ class TestHostComponent { creator: 'foobar', date: new Date().toDateString() }; - versionNumber = 1; isCurrent = false; } diff --git a/ui/src/app/metadata/configuration/component/metadata-header.component.ts b/ui/src/app/metadata/configuration/component/metadata-header.component.ts index 590be316e..cc0df37b1 100644 --- a/ui/src/app/metadata/configuration/component/metadata-header.component.ts +++ b/ui/src/app/metadata/configuration/component/metadata-header.component.ts @@ -1,6 +1,5 @@ import { Component, Input } from '@angular/core'; -import { Metadata, MetadataTypes } from '../../domain/domain.type'; -import { MetadataVersion } from '../model/version'; +import { Metadata } from '../../domain/domain.type'; import { CONFIG_DATE_FORMAT } from '../configuration.values'; @@ -12,8 +11,7 @@ import { CONFIG_DATE_FORMAT } from '../configuration.values'; export class MetadataHeaderComponent { @Input() isEnabled: boolean; - @Input() version: MetadataVersion; - @Input() versionNumber: number; + @Input() version: Metadata; @Input() isCurrent: boolean; DATE_FORMAT = CONFIG_DATE_FORMAT; diff --git a/ui/src/app/metadata/configuration/component/array-property.component.html b/ui/src/app/metadata/configuration/component/property/array-property.component.html similarity index 100% rename from ui/src/app/metadata/configuration/component/array-property.component.html rename to ui/src/app/metadata/configuration/component/property/array-property.component.html diff --git a/ui/src/app/metadata/configuration/component/array-property.component.scss b/ui/src/app/metadata/configuration/component/property/array-property.component.scss similarity index 100% rename from ui/src/app/metadata/configuration/component/array-property.component.scss rename to ui/src/app/metadata/configuration/component/property/array-property.component.scss diff --git a/ui/src/app/metadata/configuration/component/array-property.component.spec.ts b/ui/src/app/metadata/configuration/component/property/array-property.component.spec.ts similarity index 89% rename from ui/src/app/metadata/configuration/component/array-property.component.spec.ts rename to ui/src/app/metadata/configuration/component/property/array-property.component.spec.ts index 614738b06..c0dbcbb16 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/property/array-property.component.spec.ts @@ -3,13 +3,13 @@ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; -import { Property } from '../../domain/model/property'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; -import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { getStepProperty } from '../../domain/utility/configuration'; +import { Property } from '../../../domain/model/property'; +import { MockI18nModule } from '../../../../../testing/i18n.stub'; +import { SCHEMA } from '../../../../../testing/form-schema.stub'; +import { getStepProperty } from '../../../domain/utility/configuration'; import { ArrayPropertyComponent } from './array-property.component'; -import { AttributesService } from '../../domain/service/attributes.service'; -import { MockAttributeService } from '../../../../testing/attributes.stub'; +import { AttributesService } from '../../../domain/service/attributes.service'; +import { MockAttributeService } from '../../../../../testing/attributes.stub'; import { of } from 'rxjs'; @Component({ diff --git a/ui/src/app/metadata/configuration/component/array-property.component.ts b/ui/src/app/metadata/configuration/component/property/array-property.component.ts similarity index 86% rename from ui/src/app/metadata/configuration/component/array-property.component.ts rename to ui/src/app/metadata/configuration/component/property/array-property.component.ts index a17ad01da..2c4de49bd 100644 --- a/ui/src/app/metadata/configuration/component/array-property.component.ts +++ b/ui/src/app/metadata/configuration/component/property/array-property.component.ts @@ -1,9 +1,9 @@ import { Component, Input, OnChanges, Output, EventEmitter } from '@angular/core'; -import { Property } from '../../domain/model/property'; +import { Property } from '../../../domain/model/property'; import { Observable, of } from 'rxjs'; -import { AttributesService } from '../../domain/service/attributes.service'; +import { AttributesService } from '../../../domain/service/attributes.service'; import { ConfigurationPropertyComponent } from './configuration-property.component'; -import UriValidator from '../../../shared/validation/uri.validator'; +import UriValidator from '../../../../shared/validation/uri.validator'; @Component({ selector: 'array-property', diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts b/ui/src/app/metadata/configuration/component/property/configuration-property.component.spec.ts similarity index 85% rename from ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts rename to ui/src/app/metadata/configuration/component/property/configuration-property.component.spec.ts index aa7fd9478..cccfd9114 100644 --- a/ui/src/app/metadata/configuration/component/configuration-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/property/configuration-property.component.spec.ts @@ -2,11 +2,11 @@ import { Component, ViewChild, Input } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; -import { NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; -import { Property } from '../../domain/model/property'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; -import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { getStepProperties, getStepProperty } from '../../domain/utility/configuration'; +import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; +import { Property } from '../../../domain/model/property'; +import { MockI18nModule } from '../../../../../testing/i18n.stub'; +import { SCHEMA } from '../../../../../testing/form-schema.stub'; +import { getStepProperty } from '../../../domain/utility/configuration'; import { ConfigurationPropertyComponent } from './configuration-property.component'; @Component({ diff --git a/ui/src/app/metadata/configuration/component/configuration-property.component.ts b/ui/src/app/metadata/configuration/component/property/configuration-property.component.ts similarity index 91% rename from ui/src/app/metadata/configuration/component/configuration-property.component.ts rename to ui/src/app/metadata/configuration/component/property/configuration-property.component.ts index 5418bde30..7e666bc03 100644 --- a/ui/src/app/metadata/configuration/component/configuration-property.component.ts +++ b/ui/src/app/metadata/configuration/component/property/configuration-property.component.ts @@ -1,5 +1,5 @@ import { Component, Input } from '@angular/core'; -import { Property } from '../../domain/model/property'; +import { Property } from '../../../domain/model/property'; @Component({ selector: 'configuration-property', diff --git a/ui/src/app/metadata/configuration/component/filter-target-property.component.html b/ui/src/app/metadata/configuration/component/property/filter-target-property.component.html similarity index 100% rename from ui/src/app/metadata/configuration/component/filter-target-property.component.html rename to ui/src/app/metadata/configuration/component/property/filter-target-property.component.html diff --git a/ui/src/app/metadata/configuration/component/filter-target-property.component.spec.ts b/ui/src/app/metadata/configuration/component/property/filter-target-property.component.spec.ts similarity index 79% rename from ui/src/app/metadata/configuration/component/filter-target-property.component.spec.ts rename to ui/src/app/metadata/configuration/component/property/filter-target-property.component.spec.ts index 98c08d4c4..d1308787d 100644 --- a/ui/src/app/metadata/configuration/component/filter-target-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/property/filter-target-property.component.spec.ts @@ -3,15 +3,12 @@ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; -import { Property } from '../../domain/model/property'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; -import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { getStepProperty } from '../../domain/utility/configuration'; +import { Property } from '../../../domain/model/property'; +import { MockI18nModule } from '../../../../../testing/i18n.stub'; +import { SCHEMA } from '../../../../../testing/form-schema.stub'; +import { getStepProperty } from '../../../domain/utility/configuration'; import { FilterTargetPropertyComponent } from './filter-target-property.component'; -import { PrimitivePropertyComponent } from './primitive-property.component'; -import { ArrayPropertyComponentStub, PrimitivePropertyComponentStub } from '../../../../testing/property-component.stub'; -import { AttributesService } from '../../domain/service/attributes.service'; -import { of } from 'rxjs'; +import { ArrayPropertyComponentStub, PrimitivePropertyComponentStub } from '../../../../../testing/property-component.stub'; @Component({ template: ` diff --git a/ui/src/app/metadata/configuration/component/filter-target-property.component.ts b/ui/src/app/metadata/configuration/component/property/filter-target-property.component.ts similarity index 91% rename from ui/src/app/metadata/configuration/component/filter-target-property.component.ts rename to ui/src/app/metadata/configuration/component/property/filter-target-property.component.ts index 6b7ebf216..8c0e89b00 100644 --- a/ui/src/app/metadata/configuration/component/filter-target-property.component.ts +++ b/ui/src/app/metadata/configuration/component/property/filter-target-property.component.ts @@ -1,5 +1,5 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; -import { Property } from '../../domain/model/property'; +import { Property } from '../../../domain/model/property'; import { ConfigurationPropertyComponent } from './configuration-property.component'; @Component({ diff --git a/ui/src/app/metadata/configuration/component/object-property.component.html b/ui/src/app/metadata/configuration/component/property/object-property.component.html similarity index 100% rename from ui/src/app/metadata/configuration/component/object-property.component.html rename to ui/src/app/metadata/configuration/component/property/object-property.component.html diff --git a/ui/src/app/metadata/configuration/component/object-property.component.spec.ts b/ui/src/app/metadata/configuration/component/property/object-property.component.spec.ts similarity index 87% rename from ui/src/app/metadata/configuration/component/object-property.component.spec.ts rename to ui/src/app/metadata/configuration/component/property/object-property.component.spec.ts index 8817711c9..d9ddcdd97 100644 --- a/ui/src/app/metadata/configuration/component/object-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/property/object-property.component.spec.ts @@ -3,11 +3,11 @@ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; -import { Property } from '../../domain/model/property'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { Property } from '../../../domain/model/property'; +import { MockI18nModule } from '../../../../../testing/i18n.stub'; import { ObjectPropertyComponent } from './object-property.component'; -import { SCHEMA } from '../../../../testing/form-schema.stub'; -import { getStepProperty } from '../../domain/utility/configuration'; +import { SCHEMA } from '../../../../../testing/form-schema.stub'; +import { getStepProperty } from '../../../domain/utility/configuration'; import { PrimitivePropertyComponent } from './primitive-property.component'; import { ArrayPropertyComponent } from './array-property.component'; import { FilterTargetPropertyComponent } from './filter-target-property.component'; diff --git a/ui/src/app/metadata/configuration/component/object-property.component.ts b/ui/src/app/metadata/configuration/component/property/object-property.component.ts similarity index 89% rename from ui/src/app/metadata/configuration/component/object-property.component.ts rename to ui/src/app/metadata/configuration/component/property/object-property.component.ts index 1fafafa25..9eef4afbd 100644 --- a/ui/src/app/metadata/configuration/component/object-property.component.ts +++ b/ui/src/app/metadata/configuration/component/property/object-property.component.ts @@ -1,5 +1,5 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; -import { Property } from '../../domain/model/property'; +import { Property } from '../../../domain/model/property'; import { ConfigurationPropertyComponent } from './configuration-property.component'; @Component({ diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.html b/ui/src/app/metadata/configuration/component/property/primitive-property.component.html similarity index 100% rename from ui/src/app/metadata/configuration/component/primitive-property.component.html rename to ui/src/app/metadata/configuration/component/property/primitive-property.component.html diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts b/ui/src/app/metadata/configuration/component/property/primitive-property.component.spec.ts similarity index 92% rename from ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts rename to ui/src/app/metadata/configuration/component/property/primitive-property.component.spec.ts index 9ce81bfb5..dbc3eed4f 100644 --- a/ui/src/app/metadata/configuration/component/primitive-property.component.spec.ts +++ b/ui/src/app/metadata/configuration/component/property/primitive-property.component.spec.ts @@ -3,8 +3,8 @@ import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; -import { Property } from '../../domain/model/property'; -import { MockI18nModule } from '../../../../testing/i18n.stub'; +import { Property } from '../../../domain/model/property'; +import { MockI18nModule } from '../../../../../testing/i18n.stub'; import { PrimitivePropertyComponent } from './primitive-property.component'; @Component({ diff --git a/ui/src/app/metadata/configuration/component/primitive-property.component.ts b/ui/src/app/metadata/configuration/component/property/primitive-property.component.ts similarity index 100% rename from ui/src/app/metadata/configuration/component/primitive-property.component.ts rename to ui/src/app/metadata/configuration/component/property/primitive-property.component.ts diff --git a/ui/src/app/metadata/configuration/configuration.module.ts b/ui/src/app/metadata/configuration/configuration.module.ts index c55e24051..ae332ddf3 100644 --- a/ui/src/app/metadata/configuration/configuration.module.ts +++ b/ui/src/app/metadata/configuration/configuration.module.ts @@ -1,5 +1,5 @@ import { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; +import { CommonModule, DatePipe } from '@angular/common'; import { StoreModule } from '@ngrx/store'; import { EffectsModule } from '@ngrx/effects'; import { RouterModule } from '@angular/router'; @@ -11,10 +11,12 @@ import { ConfigurationComponent } from './container/configuration.component'; import { MetadataConfigurationService } from './service/configuration.service'; import * as fromConfig from './reducer'; import { MetadataConfigurationEffects } from './effect/configuration.effect'; -import { ConfigurationPropertyComponent } from './component/configuration-property.component'; -import { PrimitivePropertyComponent } from './component/primitive-property.component'; -import { ObjectPropertyComponent } from './component/object-property.component'; -import { ArrayPropertyComponent } from './component/array-property.component'; +import { ConfigurationPropertyComponent } from './component/property/configuration-property.component'; +import { PrimitivePropertyComponent } from './component/property/primitive-property.component'; +import { ObjectPropertyComponent } from './component/property/object-property.component'; +import { ArrayPropertyComponent } from './component/property/array-property.component'; +import { FilterTargetPropertyComponent } from './component/property/filter-target-property.component'; + import { MetadataOptionsComponent } from './container/metadata-options.component'; import { MetadataXmlComponent } from './container/metadata-xml.component'; import { MetadataHeaderComponent } from './component/metadata-header.component'; @@ -29,9 +31,19 @@ import { FilterModule } from '../filter/filter.module'; import { FilterConfigurationListComponent } from './component/filter-configuration-list.component'; import { FilterConfigurationListItemComponent } from './component/filter-configuration-list-item.component'; import { SharedModule } from '../../shared/shared.module'; -import { FilterTargetPropertyComponent } from './component/filter-target-property.component'; + import { RestoreComponent } from './container/restore.component'; -import { RestoreVersionEffects } from './effect/restore.effect'; +import { RestoreEffects } from './effect/restore.effect'; +import { VersionComponent } from './container/version.component'; +import { VersionOptionsComponent } from './container/version-options.component'; +import { VersionEffects } from './effect/version.effect'; +import { MetadataEditorComponent } from './component/editor.component'; +import { WizardModule } from '../../wizard/wizard.module'; +import { FormModule } from '../../schema-form/schema-form.module'; +import { RestoreEditComponent } from './container/restore-edit.component'; +import { RestoreEditStepComponent } from './container/restore-edit-step.component'; + +import { IndexResolver } from './service/index-resolver.service'; @NgModule({ declarations: [ @@ -50,7 +62,12 @@ import { RestoreVersionEffects } from './effect/restore.effect'; FilterConfigurationListComponent, FilterConfigurationListItemComponent, FilterTargetPropertyComponent, - RestoreComponent + RestoreComponent, + VersionComponent, + VersionOptionsComponent, + MetadataEditorComponent, + RestoreEditComponent, + RestoreEditStepComponent ], entryComponents: [], imports: [ @@ -60,10 +77,15 @@ import { RestoreVersionEffects } from './effect/restore.effect'; RouterModule, DomainModule, FilterModule, - SharedModule + SharedModule, + WizardModule, + FormModule ], exports: [], - providers: [] + providers: [ + DatePipe, + IndexResolver + ] }) export class MetadataConfigurationModule { static forRoot(): ModuleWithProviders { @@ -86,7 +108,8 @@ export class MetadataConfigurationModule { MetadataConfigurationEffects, MetadataHistoryEffects, CompareVersionEffects, - RestoreVersionEffects + RestoreEffects, + VersionEffects ]) ], providers: [] diff --git a/ui/src/app/metadata/configuration/configuration.routing.ts b/ui/src/app/metadata/configuration/configuration.routing.ts index dc3f5df99..fec3c84da 100644 --- a/ui/src/app/metadata/configuration/configuration.routing.ts +++ b/ui/src/app/metadata/configuration/configuration.routing.ts @@ -5,6 +5,11 @@ import { MetadataXmlComponent } from './container/metadata-xml.component'; import { MetadataHistoryComponent } from './container/metadata-history.component'; import { MetadataComparisonComponent } from './container/metadata-comparison.component'; import { RestoreComponent } from './container/restore.component'; +import { VersionComponent } from './container/version.component'; +import { VersionOptionsComponent } from './container/version-options.component'; +import { RestoreEditComponent } from './container/restore-edit.component'; +import { IndexResolver } from './service/index-resolver.service'; +import { RestoreEditStepComponent } from './container/restore-edit-step.component'; export const ConfigurationRoutes: Routes = [ { @@ -32,8 +37,35 @@ export const ConfigurationRoutes: Routes = [ component: MetadataComparisonComponent }, { - path: 'restore', - component: RestoreComponent + path: 'version/:version', + component: VersionComponent, + children: [ + { + path: 'options', + component: VersionOptionsComponent + }, + { + path: 'restore', + component: RestoreComponent + }, + { + path: 'edit', + redirectTo: 'edit/common' + }, + { + path: 'edit', + component: RestoreEditComponent, + children: [ + { + path: ':index', + component: RestoreEditStepComponent, + resolve: { + index: IndexResolver + } + } + ] + } + ] } ] } diff --git a/ui/src/app/metadata/configuration/container/configuration.component.spec.ts b/ui/src/app/metadata/configuration/container/configuration.component.spec.ts index 71bb05ab0..b1d9bc2f2 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.spec.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.spec.ts @@ -1,10 +1,9 @@ -import { Component, ViewChild, Input } from '@angular/core'; +import { Component, ViewChild } from '@angular/core'; import { TestBed, async, ComponentFixture } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { StoreModule, combineReducers } from '@ngrx/store'; import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap'; -import { MetadataConfiguration } from '../model/metadata-configuration'; import { ConfigurationComponent } from './configuration.component'; import * as fromConfiguration from '../reducer'; import * as fromProviders from '../../provider/reducer'; @@ -19,11 +18,6 @@ import { MockI18nModule } from '../../../../testing/i18n.stub'; class TestHostComponent { @ViewChild(ConfigurationComponent) public componentUnderTest: ConfigurationComponent; - - configuration: MetadataConfiguration = { - dates: [], - sections: [] - }; } describe('Metadata Configuration Page Component', () => { diff --git a/ui/src/app/metadata/configuration/container/configuration.component.ts b/ui/src/app/metadata/configuration/container/configuration.component.ts index d8c0234c6..c1e2daf35 100644 --- a/ui/src/app/metadata/configuration/container/configuration.component.ts +++ b/ui/src/app/metadata/configuration/container/configuration.component.ts @@ -1,13 +1,12 @@ -import { Component, ChangeDetectionStrategy, OnDestroy, HostListener } from '@angular/core'; -import { ActivatedRoute, Router, Scroll, Event } from '@angular/router'; -import { takeUntil, map, withLatestFrom, filter, timeout, delay } from 'rxjs/operators'; +import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { takeUntil, map } from 'rxjs/operators'; import { Store } from '@ngrx/store'; -import { Observable, Subject, interval, combineLatest } from 'rxjs'; +import { Observable, Subject } from 'rxjs'; import * as fromConfiguration from '../reducer'; import { ClearConfiguration, SetMetadata } from '../action/configuration.action'; -import { LoadHistoryRequest, ClearHistory, SelectVersion } from '../action/history.action'; import * as fromReducer from '../reducer'; @Component({ @@ -27,33 +26,14 @@ export class ConfigurationComponent implements OnDestroy { private routerState: ActivatedRoute ) { - combineLatest( - this.routerState.params, - this.routerState.queryParams - ).pipe( + this.routerState.params.pipe( takeUntil(this.ngUnsubscribe), - map(([{ id, type }, { version }]) => new SetMetadata({ + map(({ id, type, version }) => new SetMetadata({ id, type, version })) - ).subscribe(store); - - this.routerState.params.pipe( - takeUntil(this.ngUnsubscribe), - map(params => new LoadHistoryRequest({ id: params.id, type: params.type })) - ).subscribe(store); - - this.store.select(fromReducer.getVersionCollection).pipe( - filter(collection => collection && collection.length > 0), - takeUntil(this.ngUnsubscribe), - withLatestFrom( - this.routerState.queryParams - ), - map(([collection, params]) => params.version || collection && collection.length ? collection[0].id : null) - ).subscribe(version => { - this.store.dispatch(new SelectVersion(version)); - }); + ).subscribe(this.store); this.name$ = this.store.select(fromReducer.getConfigurationModelName); this.type$ = this.store.select(fromReducer.getConfigurationModelType); @@ -63,6 +43,5 @@ export class ConfigurationComponent implements OnDestroy { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); this.store.dispatch(new ClearConfiguration()); - this.store.dispatch(new ClearHistory()); } } diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html index 7117b7bf6..8e652d1c2 100644 --- a/ui/src/app/metadata/configuration/container/metadata-comparison.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.html @@ -4,7 +4,7 @@

Provider Configuration

-
@@ -14,5 +14,9 @@

Version History

- + +
+
+ + Loading...
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts index cec29c2a6..1b1834fa1 100644 --- a/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-comparison.component.ts @@ -1,10 +1,10 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; import { Observable } from 'rxjs'; import { Store } from '@ngrx/store'; import { ActivatedRoute } from '@angular/router'; import { map } from 'rxjs/operators'; -import { ConfigurationState, getVersionConfigurations, getVersionConfigurationCount } from '../reducer'; -import { CompareVersionRequest } from '../action/compare.action'; +import { ConfigurationState, getComparisonConfigurations, getComparisonConfigurationCount } from '../reducer'; +import { CompareVersionRequest, ClearVersions } from '../action/compare.action'; import { MetadataConfiguration } from '../model/metadata-configuration'; import * as fromReducer from '../reducer'; @@ -14,11 +14,12 @@ import * as fromReducer from '../reducer'; templateUrl: './metadata-comparison.component.html', styleUrls: [] }) -export class MetadataComparisonComponent { +export class MetadataComparisonComponent implements OnDestroy { versions$: Observable; numVersions$: Observable; type$: Observable; + loading$: Observable = this.store.select(fromReducer.getComparisonLoading); constructor( private store: Store, @@ -26,11 +27,16 @@ export class MetadataComparisonComponent { ) { this.activatedRoute.queryParams.pipe( map(params => params.versions), + map(versions => Array.isArray(versions) ? versions : [versions]), map(versions => new CompareVersionRequest(versions)) ).subscribe(this.store); - this.versions$ = this.store.select(getVersionConfigurations); - this.numVersions$ = this.store.select(getVersionConfigurationCount); + this.versions$ = this.store.select(getComparisonConfigurations); + this.numVersions$ = this.store.select(getComparisonConfigurationCount); this.type$ = this.store.select(fromReducer.getConfigurationModelType); } + + ngOnDestroy(): void { + this.store.dispatch(new ClearVersions()); + } } diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.html b/ui/src/app/metadata/configuration/container/metadata-history.component.html index 5291b4907..23c2b4595 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.html @@ -1,9 +1,13 @@

Version History

-
+
+
+ + Loading... +
\ No newline at end of file diff --git a/ui/src/app/metadata/configuration/container/metadata-history.component.ts b/ui/src/app/metadata/configuration/container/metadata-history.component.ts index 17f2c3caa..c2c1d0a1a 100644 --- a/ui/src/app/metadata/configuration/container/metadata-history.component.ts +++ b/ui/src/app/metadata/configuration/container/metadata-history.component.ts @@ -1,11 +1,17 @@ -import { Component, ChangeDetectionStrategy } from '@angular/core'; -import { Observable } from 'rxjs'; +import { Component, ChangeDetectionStrategy, OnDestroy } from '@angular/core'; +import { Observable, combineLatest, Subject } from 'rxjs'; import { Store } from '@ngrx/store'; -import { ConfigurationState, getVersionCollection } from '../reducer'; +import { + ConfigurationState, + getVersionCollection, + getConfigurationModelId, + getConfigurationModelKind, + getHistoryLoading +} from '../reducer'; import { MetadataVersion } from '../model/version'; -import { CompareVersionRequest } from '../action/compare.action'; import { Router, ActivatedRoute } from '@angular/router'; -import { map } from 'rxjs/operators'; +import { map, takeUntil } from 'rxjs/operators'; +import { LoadHistoryRequest, ClearHistory } from '../action/history.action'; @Component({ selector: 'metadata-history', @@ -13,15 +19,27 @@ import { map } from 'rxjs/operators'; templateUrl: './metadata-history.component.html', styleUrls: [] }) -export class MetadataHistoryComponent { +export class MetadataHistoryComponent implements OnDestroy { + + private ngUnsubscribe: Subject = new Subject(); history$: Observable; + loading$: Observable = this.store.select(getHistoryLoading); constructor( private store: Store, private router: Router, private route: ActivatedRoute ) { + combineLatest( + this.store.select(getConfigurationModelId), + this.store.select(getConfigurationModelKind) + ).pipe( + takeUntil(this.ngUnsubscribe), + map(([id, kind]) => ({ id, type: kind })), + map(request => new LoadHistoryRequest(request)) + ).subscribe(store); + this.history$ = this.store.select(getVersionCollection) .pipe(map(versions => this.sortVersionsByDate(versions))); } @@ -47,10 +65,16 @@ export class MetadataHistoryComponent { restoreVersion(version: MetadataVersion): void { this.router.navigate( - [ '../', 'restore' ], + [ '../', 'version', version.id, 'restore' ], { relativeTo: this.route } ); } + + ngOnDestroy() { + this.ngUnsubscribe.next(); + this.ngUnsubscribe.complete(); + this.store.dispatch(new ClearHistory()); + } } diff --git a/ui/src/app/metadata/configuration/container/metadata-options.component.html b/ui/src/app/metadata/configuration/container/metadata-options.component.html index ebed36bf3..390d6981c 100644 --- a/ui/src/app/metadata/configuration/container/metadata-options.component.html +++ b/ui/src/app/metadata/configuration/container/metadata-options.component.html @@ -6,9 +6,8 @@