From 9ad339c758fba27a0baf9a9c1142fa79d8f39037 Mon Sep 17 00:00:00 2001 From: do4gr Date: Sat, 5 May 2018 15:43:32 +0200 Subject: [PATCH] add more test cases --- ...ionalBackRelationDuringMigrationSpec.scala | 66 +++++++++ ...angingFromRelationToScalarOrBackSpec.scala | 125 ++++++++++++++++++ .../inference/MigrationStepsInferrer.scala | 10 +- .../com/prisma/deploy/schema/Errors.scala | 2 +- 4 files changed, 197 insertions(+), 6 deletions(-) create mode 100644 server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/ChangingFromRelationToScalarOrBackSpec.scala diff --git a/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/AddingOptionalBackRelationDuringMigrationSpec.scala b/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/AddingOptionalBackRelationDuringMigrationSpec.scala index aadac9092f..43604fe158 100644 --- a/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/AddingOptionalBackRelationDuringMigrationSpec.scala +++ b/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/AddingOptionalBackRelationDuringMigrationSpec.scala @@ -235,4 +235,70 @@ class AddingOptionalBackRelationDuringMigrationSpec extends FlatSpec with Matche res.toString should be( """{"data":{"deploy":{"migration":{"applied":0,"revision":0},"errors":[{"description":"You are adding a singular backrelation field to a type but there are already pairs in the relation that would violate that constraint."}],"warnings":[]}}}""") } + + "Adding several missing back-relations of list type" should "work even when there are already multiple relation pairs" in { + + val schema = + """type Team { + | name: String! @unique + |} + | + |type Match { + | number: Int @unique + | teamLeft: Team @relation(name: "TeamMatchLeft") + | teamRight: Team @relation(name: "TeamMatchRight") + | winner: Team @relation(name: "TeamMatchWinner") + |}""" + + val (project, _) = setupProject(schema) + + apiServer.query( + """mutation{createMatch(data:{ + | number:1 + | teamLeft:{create:{name: "Bayern"}}, + | teamRight:{create:{name: "Real"}}, + | winner:{connect:{name: "Real"}} + | } + |){number}}""", + project + ) + + apiServer.query( + """mutation{createMatch(data:{ + | number:2 + | teamLeft:{connect:{name: "Bayern"}}, + | teamRight:{connect:{name: "Real"}}, + | winner:{connect:{name: "Real"}} + | } + |){number}}""", + project + ) + + val matches = apiServer.query("""{matches{number, teamLeft{name},teamRight{name},winner{name}}}""", project) + matches.toString should be( + """{"data":{"matches":[{"number":1,"teamLeft":{"name":"Bayern"},"teamRight":{"name":"Real"},"winner":{"name":"Real"}},{"number":2,"teamLeft":{"name":"Bayern"},"teamRight":{"name":"Real"},"winner":{"name":"Real"}}]}}""") + + val teams = apiServer.query("""{teams{name}}""", project) + teams.toString should be("""{"data":{"teams":[{"name":"Bayern"},{"name":"Real"}]}}""") + + val schema1 = + """type Team { + | name: String! @unique + | wins: [Match!]! @relation(name: "TeamMatchWinner") + | lefts: [Match!]! @relation(name: "TeamMatchLeft") + |} + | + |type Match { + | number: Int @unique + | teamLeft: Team @relation(name: "TeamMatchLeft") + | teamRight: Team @relation(name: "TeamMatchRight") + | winner: Team @relation(name: "TeamMatchWinner") + |}""" + + val updatedProject = deployServer.deploySchema(project, schema1) + + val updatedTeams = apiServer.query("""{teams{name, wins{number}, lefts{number}}}""", updatedProject) + updatedTeams.toString should be( + """{"data":{"teams":[{"name":"Bayern","wins":[],"lefts":[{"number":1},{"number":2}]},{"name":"Real","wins":[{"number":1},{"number":2}],"lefts":[]}]}}""") + } } diff --git a/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/ChangingFromRelationToScalarOrBackSpec.scala b/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/ChangingFromRelationToScalarOrBackSpec.scala new file mode 100644 index 0000000000..2b93e90c7c --- /dev/null +++ b/server/integration-tests/integration-tests-mysql/src/test/scala/com/prisma/integration/ChangingFromRelationToScalarOrBackSpec.scala @@ -0,0 +1,125 @@ +package com.prisma.integration + +import org.scalatest.{FlatSpec, Matchers} + +class ChangingFromRelationToScalarOrBackSpec extends FlatSpec with Matchers with IntegrationBaseSpec { + + "Changing a field from scalar to relation" should "work when there is no data yet" in { + + val schema = + """type A { + | a: String! @unique + | b: String + |} + | + |type B { + | b: String! @unique + |}""" + + val (project, _) = setupProject(schema) + + val schema1 = + """type A { + | a: String! @unique + | b: B + |} + | + |type B { + | b: String! @unique + |}""" + + deployServer.deploySchema(project, schema1) + } + + "Changing a field from scalar to relation" should "work when there is already data and should delete the old column" in { + + val schema = + """type A { + | a: String! @unique + | b: String + |} + | + |type B { + | b: String! @unique + |}""" + + val (project, _) = setupProject(schema) + + apiServer.query("""mutation{createA(data:{a:"A", b: "B"}){a}}""", project) + + val as = apiServer.query("""{as{a}}""", project) + as.toString should be("""{"data":{"as":[{"a":"A"}]}}""") + + val schema1 = + """type A { + | a: String! @unique + | b: B + |} + | + |type B { + | b: String! @unique + |}""" + + deployServer.deploySchemaThatMustWarn(project, schema1, force = true) + } + + "Changing a relation to scalar" should "work when there is no data yet" in { + + val schema = + """type A { + | a: String! @unique + | b: B + |} + | + |type B { + | b: String! @unique + |}""" + + val (project, _) = setupProject(schema) + + val schema1 = + """type A { + | a: String! @unique + | b: String + |} + | + |type B { + | b: String! @unique + |}""" + + deployServer.deploySchema(project, schema1) + } + + "Changing a relation to scalar" should "work when there is already data" in { + + val schema = + """type A { + | a: String! @unique + | b: B + |} + | + |type B { + | b: String! @unique + |}""" + + val (project, _) = setupProject(schema) + + apiServer.query("""mutation{createA(data:{a:"A", b: {b: "B"}}){a}}""", project) + + val as = apiServer.query("""{as{a, b{b}}}""", project) + as.toString should be("""{"data":{"as":[{"a":"A","b":{"b":"B"}}]}}""") + + val schema1 = + """type A { + | a: String! @unique + | b: String + |} + | + |type B { + | b: String! @unique + |}""" + + deployServer.deploySchema(project, schema1) + } + +} diff --git a/server/servers/deploy/src/main/scala/com/prisma/deploy/migration/inference/MigrationStepsInferrer.scala b/server/servers/deploy/src/main/scala/com/prisma/deploy/migration/inference/MigrationStepsInferrer.scala index 09ab869dc1..e2625e9d19 100644 --- a/server/servers/deploy/src/main/scala/com/prisma/deploy/migration/inference/MigrationStepsInferrer.scala +++ b/server/servers/deploy/src/main/scala/com/prisma/deploy/migration/inference/MigrationStepsInferrer.scala @@ -1,6 +1,6 @@ package com.prisma.deploy.migration.inference -import com.prisma.deploy.schema.UpdatedRelationAmbigous +import com.prisma.deploy.schema.UpdatedRelationAmbiguous import com.prisma.shared.models._ trait MigrationStepsInferrer { @@ -258,8 +258,8 @@ case class MigrationStepsInferrerImpl(previousSchema: Schema, nextSchema: Schema val previousRelationCountBetweenModels = previousSchema.relations.count(relation => relation.connectsTheModels(previousModelAId, previousModelBId)) if (nextRelation.name == nextGeneratedRelationName && nextRelationCountBetweenModels == 1 && previousRelationCountBetweenModels > 1) - throw UpdatedRelationAmbigous( - s"There is a relation ambiguity during the migration. The ambiguity is on a relation between ${previousRelation.modelAId} and ${previousRelation.modelBId}.") + throw UpdatedRelationAmbiguous( + s"There is a relation ambiguity during the migration. The ambiguity is on a relation between ${previousRelation.modelAId} and ${previousRelation.modelBId}. Please name relations or change the schema in steps.") val isNameRemovalOfPreviouslyNamedRelation = nextRelation.name == nextGeneratedRelationName && nextRelationCountBetweenModels == 1 && previousRelationCountBetweenModels == 1 (relationNameMatches || isNameRemovalOfPreviouslyNamedRelation) && (refersToModelsExactlyRight || refersToModelsSwitched) @@ -293,8 +293,8 @@ case class MigrationStepsInferrerImpl(previousSchema: Schema, nextSchema: Schema val nextRelationCountBetweenModels = nextSchema.relations.count(relation => relation.connectsTheModels(nextModelAId, nextModelBId)) if (previousRelation.name == previousGeneratedRelationName && nextRelationCountBetweenModels > 1 && previousRelationCountBetweenModels == 1) - throw UpdatedRelationAmbigous( - s"There is a relation ambiguity during the migration. Please first name the old relation on your schema. The ambiguity is on a relation between ${previousRelation.modelAId} and ${previousRelation.modelBId}.") + throw UpdatedRelationAmbiguous( + s"There is a relation ambiguity during the migration. Please first name the old relation on your schema. The ambiguity is on a relation between ${previousRelation.modelAId} and ${previousRelation.modelBId}. Please name relations or change the schema in steps.") val isRenameOfPreviouslyUnnamedRelation = previousRelation.name == previousGeneratedRelationName && nextRelationCountBetweenModels == 1 && previousRelationCountBetweenModels == 1 diff --git a/server/servers/deploy/src/main/scala/com/prisma/deploy/schema/Errors.scala b/server/servers/deploy/src/main/scala/com/prisma/deploy/schema/Errors.scala index 38e20218b9..ed62ba0b23 100644 --- a/server/servers/deploy/src/main/scala/com/prisma/deploy/schema/Errors.scala +++ b/server/servers/deploy/src/main/scala/com/prisma/deploy/schema/Errors.scala @@ -21,7 +21,7 @@ object TokenExpired extends AbstractDeployApiError(s"Authentication token is exp case class InvalidQuery(reason: String) extends AbstractDeployApiError(reason, 3017) -case class UpdatedRelationAmbigous(reason: String) extends AbstractDeployApiError(reason, 3018) +case class UpdatedRelationAmbiguous(reason: String) extends AbstractDeployApiError(reason, 3018) // 40xx case class InvalidProjectId(projectId: ProjectId)