Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NU-1893] Fix "Failed to get node validation" when opening fragment node details for referencing non-existing fragment #7190

Merged
merged 3 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package pl.touk.nussknacker.ui.process.fragment

import cats.implicits.toTraverseOps
import pl.touk.nussknacker.engine.api.process.{ProcessName, ProcessingType}
import pl.touk.nussknacker.engine.canonicalgraph.CanonicalProcess
import pl.touk.nussknacker.ui.process.ScenarioQuery
import pl.touk.nussknacker.ui.process.repository.FetchingProcessRepository
import pl.touk.nussknacker.ui.process.repository.ProcessDBQueryRepository.ProcessNotFoundError
import pl.touk.nussknacker.ui.security.api.LoggedUser

import scala.concurrent.duration._
Expand Down Expand Up @@ -46,10 +46,7 @@ class DefaultFragmentRepository(processRepository: FetchingProcessRepository[Fut
)(implicit user: LoggedUser): Future[Option[CanonicalProcess]] = {
processRepository
.fetchProcessId(fragmentName)
.flatMap { processIdOpt =>
val processId = processIdOpt.getOrElse(throw ProcessNotFoundError(fragmentName))
processRepository.fetchLatestProcessDetailsForProcessId[CanonicalProcess](processId)
}
.flatMap(_.map(processRepository.fetchLatestProcessDetailsForProcessId[CanonicalProcess]).sequence.map(_.flatten))
.map(_.map(_.json))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,22 +499,34 @@ class NodesApiHttpServiceBusinessSpec
|}""".stripMargin)
}

"return 404 for not existent fragment validation" in {
val fragmentName = "fragment"
"return 200 for fragment input node referencing fragment that doesn't exist" in {
val nonExistingFragmentName = "non-existing-fragment"

given()
.applicationState {
createSavedScenario(exampleScenario)
}
.basicAuthAllPermUser()
.jsonBody(exampleNodeValidationRequestForFragment(fragmentName))
.jsonBody(exampleNodeValidationRequestForFragment(nonExistingFragmentName))
.when()
.post(s"$nuDesignerHttpAddress/api/nodes/${exampleScenario.name}/validation")
.Then()
.statusCode(404)
.body(
equalTo(s"No scenario $fragmentName found")
)
.statusCode(200)
.equalsJsonBody(s"""{
| "parameters": null,
| "expressionType": null,
| "validationErrors": [
| {
| "typ": "UnknownFragment",
| "message": "Unknown fragment",
| "description": "Node fragment uses fragment non-existing-fragment which is missing",
| "fieldName": null,
| "errorType": "SaveAllowed",
| "details": null
| }
| ],
| "validationPerformed": true
|}""".stripMargin)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import akka.http.scaladsl.testkit.ScalatestRouteTest
import org.scalatest.BeforeAndAfterEach
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import pl.touk.nussknacker.engine.api.process.ProcessName
import pl.touk.nussknacker.test.VeryPatientScalaFutures
import pl.touk.nussknacker.test.utils.domain.ProcessTestData.sampleFragmentName
import pl.touk.nussknacker.test.base.it.NuResourcesTest
Expand Down Expand Up @@ -36,4 +37,8 @@ class FragmentRepositorySpec
)
}

it should "return None for missing fragment" in {
fragmentRepository.fetchLatestFragment(ProcessName("non-existing-fragment"))(adminUser).futureValue shouldBe None
}

}
1 change: 1 addition & 0 deletions docs/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
* [#7193](https://github.com/TouK/nussknacker/pull/7193) Provide tooltips to the scenarios list and scenario details elements
* [#7187](https://github.com/TouK/nussknacker/pull/7187) Fix "Failed to get node validation" when using literal lists that mixes different types of elements
* [#7192](https://github.com/TouK/nussknacker/pull/7192) Fix "Failed to get node validation" when opening node details referencing non-existing component
* [#7190](https://github.com/TouK/nussknacker/pull/7190) Fix "Failed to get node validation" when opening fragment node details for referencing non-existing fragment

## 1.17

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,27 @@ class NodeDataValidatorSpec extends AnyFunSuite with Matchers with Inside with T
}
}

test("should return business error when fragment input node referencing fragment that doesn't exist") {
validate(
FragmentInput(
"frInput",
FragmentRef(
"non-existing-fragment",
List(NodeParameter(ParameterName("param1"), "145".spel)),
Map("out1" -> "test1")
)
),
ValidationContext.empty,
outgoingEdges = List(OutgoingEdge("any", Some(FragmentOutput("out1"))))
) should matchPattern {
case ValidationPerformed(
List(UnknownFragment("non-existing-fragment", "frInput")),
None,
None
) =>
}
}

test("should validate fragment parameters") {
inside(
validate(
Expand Down
Loading