From 9126e5d26b303877249e21391c87a22542060e80 Mon Sep 17 00:00:00 2001 From: sanyavertolet Date: Tue, 23 Aug 2022 15:52:30 +0300 Subject: [PATCH 1/2] Test fixes ### What's done: * Added (returned back) testSuiteSelector for general tests - all the avaliable ones * Fixed an issue with TestSuiteSelector in browser mode - now input form is cleared when an entity from avaliable list is chosen * Fixed an issue with unclosing modal - now when TestSuiteSource is successfully created, a new request for a fetch is sent (#1079) --- .../controllers/TestSuitesSourceController.kt | 19 ++++++++- .../service/TestSuitesSourceService.kt | 5 +++ .../basic/TestSuiteSourceCreationComponent.kt | 10 +++++ .../contests/ContestCreationComponent.kt | 6 +-- .../testsuiteselector/TestSuiteSelector.kt | 39 +++++++++++++++++-- .../TestSuiteSelectorBrowserMode.kt | 37 ++++++++++-------- 6 files changed, 91 insertions(+), 25 deletions(-) diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/TestSuitesSourceController.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/TestSuitesSourceController.kt index a6c8dfd31b..1cded31631 100644 --- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/TestSuitesSourceController.kt +++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/controllers/TestSuitesSourceController.kt @@ -351,8 +351,7 @@ class TestSuitesSourceController( when (testSuitesSourceService.createSourceIfNotPresent(testSuitesSource)) { SourceSaveStatus.EXIST -> Mono.just(ResponseEntity.status(HttpStatus.CONFLICT).body(SourceSaveStatus.EXIST)) SourceSaveStatus.CONFLICT -> Mono.just(ResponseEntity.status(HttpStatus.CONFLICT).body(SourceSaveStatus.CONFLICT)) - SourceSaveStatus.NEW -> testSuitesSourceService.fetch(testSuitesSource.toDto()) - .map { ResponseEntity.ok(SourceSaveStatus.NEW) } + SourceSaveStatus.NEW -> Mono.just(ResponseEntity.ok(SourceSaveStatus.NEW)) } } @@ -513,6 +512,22 @@ class TestSuitesSourceController( } } + @GetMapping("/api/$v1/test-suites-sources/avaliable") + @RequiresAuthorizationSourceHeader + @PreAuthorize("permitAll()") + @Operation( + method = "GET", + summary = "Get organizations with public test suite sources.", + description = "Get list of organizations with public test suite sources", + ) + @ApiResponse(responseCode = "200", description = "Successfully fetched organizations with public test suite sources.") + fun getOrganizationNamesWithPublicTestSuiteSources( + authentication: Authentication, + ): Mono = testSuitesSourceService.getAvaliableTestSuiteSources().toMono() + .map {testSuitesSourceList -> + testSuitesSourceList.map { it.toDto() } + } + private fun TestSuitesSourceDto.downloadSnapshot( version: String ): Mono = testSuitesSourceSnapshotStorage.findKey(organizationName, name, version) diff --git a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/TestSuitesSourceService.kt b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/TestSuitesSourceService.kt index 83dc331337..6d3120cda6 100644 --- a/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/TestSuitesSourceService.kt +++ b/save-backend/src/main/kotlin/com/saveourtool/save/backend/service/TestSuitesSourceService.kt @@ -166,6 +166,11 @@ class TestSuitesSourceService( } } + /** + * @return list of organizations that have open public test suite sources + */ + fun getAvaliableTestSuiteSources(): List = testSuitesSourceRepository.findAll() + /** * @param testSuitesSource test suites source which requested to be fetched * @return empty response diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/TestSuiteSourceCreationComponent.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/TestSuiteSourceCreationComponent.kt index 0add02f189..8e00c6c420 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/TestSuiteSourceCreationComponent.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/TestSuiteSourceCreationComponent.kt @@ -103,6 +103,15 @@ fun ChildrenBuilder.showTestSuiteSourceCreationModal( private fun testSuiteSourceCreationComponent() = FC { props -> val (testSuiteSource, setTestSuiteSource) = useState(TestSuitesSourceDto.empty.copy(organizationName = props.organizationName)) val (saveStatus, setSaveStatus) = useState(null) + val fetchTestSuiteSource = useRequest { + post( + url = "$apiUrl/test-suites-sources/${testSuiteSource.organizationName}/${testSuiteSource.name}/fetch", + headers = jsonHeaders, + body = undefined, + loadingHandler = ::noopLoadingHandler, + responseHandler = ::noopResponseHandler, + ) + } val onSubmitButtonPressed = useRequest { val response = post( url = "/api/$v1/test-suites-sources/create", @@ -112,6 +121,7 @@ private fun testSuiteSourceCreationComponent() = FC()) diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/contests/ContestCreationComponent.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/contests/ContestCreationComponent.kt index 4fe8e9029e..7d985ea22f 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/contests/ContestCreationComponent.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/contests/ContestCreationComponent.kt @@ -4,7 +4,7 @@ package com.saveourtool.save.frontend.components.basic.contests import com.saveourtool.save.entities.ContestDto import com.saveourtool.save.frontend.components.basic.* -import com.saveourtool.save.frontend.components.basic.testsuiteselector.showPublicTestSuitesSelectorModal +import com.saveourtool.save.frontend.components.basic.testsuiteselector.showGeneralTestSuitesSelectorModal import com.saveourtool.save.frontend.externals.modal.CssProperties import com.saveourtool.save.frontend.externals.modal.Styles import com.saveourtool.save.frontend.externals.modal.modal @@ -150,10 +150,10 @@ private fun contestCreationComponent() = FC { pro div { className = ClassName("card") contestCreationCard { - showPublicTestSuitesSelectorModal( + showGeneralTestSuitesSelectorModal( contestDto.testSuiteIds, testSuitesSelectorWindowOpenness, - useState(emptyList()) + useState(emptyList()), ) { setContestDto(contestDto.copy(testSuiteIds = it)) } diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelector.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelector.kt index 2ac3119cf7..fc34dd4035 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelector.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelector.kt @@ -36,9 +36,14 @@ external interface TestSuiteSelectorProps : Props { /** * Specific organization name which reduces list of test suites source. - * If it's null we show public tests + * If null, all the test suites are shown */ var specificOrganizationName: String? + + /** + * If this flag is true public tests will be shown + */ + var isStandardMode: Boolean } /** @@ -52,6 +57,8 @@ enum class TestSuiteSelectorMode { } /** + * Browse standard test suites + * * @param initTestSuiteIds initial value * @param windowOpenness state to control openness of window * @param testSuiteIdsInSelectorState state for intermediate result in selector @@ -63,10 +70,29 @@ fun ChildrenBuilder.showPublicTestSuitesSelectorModal( testSuiteIdsInSelectorState: StateInstance>, setSelectedTestSuiteIds: (List) -> Unit, ) { - showTestSuitesSelectorModal(null, initTestSuiteIds, windowOpenness, testSuiteIdsInSelectorState, setSelectedTestSuiteIds) + showTestSuitesSelectorModal(null, true, initTestSuiteIds, windowOpenness, testSuiteIdsInSelectorState, setSelectedTestSuiteIds) +} + +/** + * Browse all the avaliable test suites. + * + * @param initTestSuiteIds initial value + * @param windowOpenness state to control openness of window + * @param testSuiteIdsInSelectorState state for intermediate result in selector + * @param setSelectedTestSuiteIds consumer for result + */ +fun ChildrenBuilder.showGeneralTestSuitesSelectorModal( + initTestSuiteIds: List, + windowOpenness: WindowOpenness, + testSuiteIdsInSelectorState: StateInstance>, + setSelectedTestSuiteIds: (List) -> Unit, +) { + showTestSuitesSelectorModal(null, false, initTestSuiteIds, windowOpenness, testSuiteIdsInSelectorState, setSelectedTestSuiteIds) } /** + * Browse test suites of a given organization + * * @param organizationName * @param initTestSuiteIds initial value * @param windowOpenness state to control openness of window @@ -80,11 +106,13 @@ fun ChildrenBuilder.showPrivateTestSuitesSelectorModal( testSuiteIdsInSelectorState: StateInstance>, setSelectedTestSuiteIds: (List) -> Unit, ) { - showTestSuitesSelectorModal(organizationName, initTestSuiteIds, windowOpenness, testSuiteIdsInSelectorState, setSelectedTestSuiteIds) + showTestSuitesSelectorModal(organizationName, false, initTestSuiteIds, windowOpenness, testSuiteIdsInSelectorState, setSelectedTestSuiteIds) } +@Suppress("TOO_MANY_PARAMETERS", "LongParameterList") private fun ChildrenBuilder.showTestSuitesSelectorModal( specificOrganizationName: String?, + isStandardMode: Boolean, initTestSuiteIds: List, windowOpenness: WindowOpenness, testSuiteIdsInSelectorState: StateInstance>, @@ -102,7 +130,7 @@ private fun ChildrenBuilder.showTestSuitesSelectorModal( currentlySelectedTestSuiteIds = initTestSuiteIds windowOpenness.closeWindow() } - showTestSuitesSelectorModal(windowOpenness.isOpen(), specificOrganizationName, initTestSuiteIds, onSubmit, onTestSuiteIdUpdate, onCancel) + showTestSuitesSelectorModal(windowOpenness.isOpen(), specificOrganizationName, isStandardMode, initTestSuiteIds, onSubmit, onTestSuiteIdUpdate, onCancel) } @Suppress( @@ -114,6 +142,7 @@ private fun ChildrenBuilder.showTestSuitesSelectorModal( private fun ChildrenBuilder.showTestSuitesSelectorModal( isOpen: Boolean, specificOrganizationName: String?, + isStandardMode: Boolean, preselectedTestSuiteIds: List, onSubmit: () -> Unit, onTestSuiteIdUpdate: (List) -> Unit, @@ -150,6 +179,7 @@ private fun ChildrenBuilder.showTestSuitesSelectorModal( this.onTestSuiteIdUpdate = onTestSuiteIdUpdate this.preselectedTestSuiteIds = preselectedTestSuiteIds this.specificOrganizationName = specificOrganizationName + this.isStandardMode = isStandardMode } } @@ -233,6 +263,7 @@ private fun testSuiteSelector() = FC { props -> this.onTestSuiteIdsUpdate = props.onTestSuiteIdUpdate this.preselectedTestSuiteIds = props.preselectedTestSuiteIds this.specificOrganizationName = props.specificOrganizationName + this.isStandardMode = props.isStandardMode } TestSuiteSelectorMode.SEARCH -> testSuiteSelectorSearchMode { this.onTestSuiteIdsUpdate = props.onTestSuiteIdUpdate diff --git a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelectorBrowserMode.kt b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelectorBrowserMode.kt index 979d7f5f09..558514f7e8 100644 --- a/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelectorBrowserMode.kt +++ b/save-frontend/src/main/kotlin/com/saveourtool/save/frontend/components/basic/testsuiteselector/TestSuiteSelectorBrowserMode.kt @@ -48,9 +48,14 @@ external interface TestSuiteSelectorBrowserModeProps : Props { /** * Specific organization name which reduces list of test suites source. - * If it's null we show public tests + * If null, all the test suites are shown */ var specificOrganizationName: String? + + /** + * If this flag is true public tests will be shown + */ + var isStandardMode: Boolean } @Suppress( @@ -158,22 +163,20 @@ private fun testSuiteSelectorBrowserMode() = FC>(emptyList()) val (availableTestSuiteSources, setAvailableTestSuiteSources) = useState>(emptyList()) + useRequest { - val response = props.specificOrganizationName?.let { organizationName -> - get( - url = "$apiUrl/test-suites-sources/$organizationName/list", - headers = jsonHeaders, - loadingHandler = ::noopLoadingHandler, - responseHandler = ::noopResponseHandler, - ) - } ?: run { - get( - url = "$apiUrl/test-suites-sources/public-list", - headers = jsonHeaders, - loadingHandler = ::noopLoadingHandler, - responseHandler = ::noopResponseHandler, - ) + val url = when { + props.isStandardMode -> "$apiUrl/test-suites-sources/public-list" + props.specificOrganizationName != null -> "$apiUrl/test-suites-sources/avaliable" + else -> "$apiUrl/test-suites-sources/${props.specificOrganizationName}/list" } + val response = get( + url = url, + headers = jsonHeaders, + loadingHandler = ::noopLoadingHandler, + responseHandler = ::noopResponseHandler, + ) + val testSuitesSources: TestSuitesSourceDtoList = response.decodeFromJsonString() setAvailableOrganizations(testSuitesSources.map { it.organizationName }.distinct()) setAvailableTestSuiteSources(testSuitesSources.map { it.name }) @@ -291,7 +294,6 @@ private fun testSuiteSelectorBrowserMode() = FC setSelectedOrganization(organization) + setNamePrefix("") } selectedTestSuiteSource == null -> showAvaliableOptions( availableTestSuiteSources.filter { it.contains(namePrefix, true) } ) { testSuiteSource -> setSelectedTestSuiteSource(testSuiteSource) + setNamePrefix("") } selectedTestSuiteVersion == null -> showAvaliableOptions( availableTestSuitesVersions.filter { it.contains(namePrefix, true) } ) { testSuiteVersion -> setSelectedTestSuiteVersion(testSuiteVersion) + setNamePrefix("") } else -> showAvaliableTestSuites( availableTestSuites.filter { it.name.contains(namePrefix, true) }, From ffc01e9018afb91c3eb0f07d17945ddffd82ce9a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 23 Aug 2022 12:59:22 +0000 Subject: [PATCH 2/2] Update backend-api-docs.json --- save-backend/backend-api-docs.json | 133 ++++++++++++++--------------- 1 file changed, 66 insertions(+), 67 deletions(-) diff --git a/save-backend/backend-api-docs.json b/save-backend/backend-api-docs.json index 14f0560af1..90dfccc0e7 100644 --- a/save-backend/backend-api-docs.json +++ b/save-backend/backend-api-docs.json @@ -57,36 +57,6 @@ "schema": { "type": "string" } - }, - { - "name": "version", - "in": "query", - "description": "version of uploading snapshot", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "creationTime", - "in": "query", - "description": "creationTime of uploading snapshot", - "required": true, - "schema": { - "type": "integer", - "format": "int64" - } - }, - { - "name": "content", - "description": "content of uploading snapshot", - "required": true - }, - { - "name": "X-Authorization-Source", - "in": "header", - "required": true, - "example": "basic" } ], "requestBody": { @@ -99,7 +69,16 @@ "type": "object", "properties": { "content": { - "$ref": "#/components/schemas/Part" + "description": "content of uploading snapshot" + }, + "version": { + "description": "version of uploading snapshot" + }, + "creationTime": { + "description": "creationTime of uploading snapshot" + }, + "X-Authorization-Source": { + "example": "basic" } } } @@ -2032,28 +2011,6 @@ "files" ], "operationId": "uploadImage", - "parameters": [ - { - "name": "owner", - "in": "query", - "required": true, - "schema": { - "type": "string" - } - }, - { - "name": "type", - "in": "query", - "required": true, - "schema": { - "type": "string", - "enum": [ - "ORGANIZATION", - "USER" - ] - } - } - ], "requestBody": { "content": { "multipart/form-data": { @@ -2066,7 +2023,9 @@ "file": { "type": "string", "format": "binary" - } + }, + "owner": {}, + "type": {} } } } @@ -2113,15 +2072,6 @@ "schema": { "type": "string" } - }, - { - "name": "returnShortFileInfo", - "in": "query", - "required": false, - "schema": { - "type": "boolean", - "default": true - } } ], "requestBody": { @@ -2136,7 +2086,8 @@ "file": { "type": "string", "format": "binary" - } + }, + "returnShortFileInfo": {} } } } @@ -4032,6 +3983,57 @@ ] } }, + "/api/v1/test-suites-sources/avaliable": { + "get": { + "tags": [ + "test-suites-source" + ], + "summary": "Get organizations with public test suite sources.", + "description": "Get list of organizations with public test suite sources", + "operationId": "getOrganizationNamesWithPublicTestSuiteSources", + "parameters": [ + { + "name": "X-Authorization-Source", + "in": "header", + "required": true, + "example": "basic" + } + ], + "responses": { + "200": { + "description": "Successfully fetched organizations with public test suite sources.", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TestSuitesSourceDto" + } + } + } + } + }, + "401": { + "description": "Unauthorized", + "content": { + "*/*": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/TestSuitesSourceDto" + } + } + } + } + } + }, + "security": [ + { + "basic": [] + } + ] + } + }, "/api/v1/projects/": { "get": { "tags": [ @@ -6679,9 +6681,6 @@ "Unit": { "type": "object" }, - "Part": { - "type": "object" - }, "GitDto": { "required": [ "url"