diff --git a/contract/src/main/kotlin/io/provenance/scope/loan/contracts/RecordLoanContract.kt b/contract/src/main/kotlin/io/provenance/scope/loan/contracts/RecordLoanContract.kt index ec5095e..16f24dd 100644 --- a/contract/src/main/kotlin/io/provenance/scope/loan/contracts/RecordLoanContract.kt +++ b/contract/src/main/kotlin/io/provenance/scope/loan/contracts/RecordLoanContract.kt @@ -13,7 +13,6 @@ import io.provenance.scope.loan.LoanScopeFacts import io.provenance.scope.loan.LoanScopeProperties.assetLoanKey import io.provenance.scope.loan.LoanScopeProperties.assetMismoKey import io.provenance.scope.loan.utility.ContractRequirementType.VALID_INPUT -import io.provenance.scope.loan.utility.documentModificationValidation import io.provenance.scope.loan.utility.documentValidation import io.provenance.scope.loan.utility.eNoteInputValidation import io.provenance.scope.loan.utility.isSet @@ -24,7 +23,6 @@ import io.provenance.scope.loan.utility.orError import io.provenance.scope.loan.utility.raiseError import io.provenance.scope.loan.utility.servicingRightsInputValidation import io.provenance.scope.loan.utility.toFigureTechLoan -import io.provenance.scope.loan.utility.toMISMOLoan import io.provenance.scope.loan.utility.tryUnpackingAs import io.provenance.scope.loan.utility.uliValidation import io.provenance.scope.loan.utility.updateServicingData @@ -61,8 +59,8 @@ open class RecordLoanContract( newAsset.type.isNotBlank() orError "Asset is missing type", ) } - if (newAsset.containsKv(assetLoanKey) xor newAsset.containsKv(assetMismoKey)) { - newAsset.kvMap[assetLoanKey]?.let { newLoanValue -> + if (newAsset.containsKv(assetLoanKey)) { + newAsset.kvMap[assetLoanKey]!!.let { newLoanValue -> newLoanValue.tryUnpackingAs("input asset's \"${assetLoanKey}\"") { newLoan -> if (existingAsset.isSet()) { existingAsset!!.kvMap[assetLoanKey]?.toFigureTechLoan()?.also { existingLoan -> @@ -70,7 +68,7 @@ open class RecordLoanContract( (existingLoan.id == newLoan.id) orError "Cannot change loan ID", (existingLoan.originatorName == newLoan.originatorName) orError "Cannot change loan originator name", ) - } ?: raiseError("The input asset had key \"${assetLoanKey}\" but the existing asset did not") + } } else { requireThat( newLoan.id.isValid() orError "Loan must have valid ID", @@ -81,24 +79,13 @@ open class RecordLoanContract( } } } - newAsset.kvMap[assetMismoKey]?.let { newLoanValue -> - newLoanValue.tryUnpackingAs("input asset's \"${assetMismoKey}\"") { newLoan -> - documentValidation(newLoan.document) - if (existingAsset.isSet()) { - existingAsset!!.kvMap[assetMismoKey]?.toMISMOLoan()?.also { existingLoan -> - // TODO: Allow doc with different checksum to replace existing one or not? - documentModificationValidation(existingLoan.document, newLoan.document) - requireThat( - (existingLoan.uli == newLoan.uli) orError "Cannot change loan ULI", - ) - } ?: raiseError("The input asset had key \"${assetMismoKey}\" but the existing asset did not") - } else { - uliValidation(newLoan.uli) - } - } - } } else { - raiseError("Exactly one of \"${assetLoanKey}\" or \"${assetMismoKey}\" must be a key in the input asset") + raiseError("\"${assetLoanKey}\" must be a key in the input asset") + } + newAsset.kvMap[assetMismoKey]?.let { newMismoLoanValue -> + newMismoLoanValue.tryUnpackingAs("input asset's \"${assetMismoKey}\"") { newLoan -> + documentValidation(newLoan.document) + } } } } diff --git a/contract/src/test/kotlin/io/provenance/scope/loan/contracts/RecordLoanContractUnitTest.kt b/contract/src/test/kotlin/io/provenance/scope/loan/contracts/RecordLoanContractUnitTest.kt index 89fbabf..b226cca 100644 --- a/contract/src/test/kotlin/io/provenance/scope/loan/contracts/RecordLoanContractUnitTest.kt +++ b/contract/src/test/kotlin/io/provenance/scope/loan/contracts/RecordLoanContractUnitTest.kt @@ -7,8 +7,6 @@ import io.kotest.core.test.TestCaseOrder import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContain import io.kotest.matchers.string.shouldContainIgnoringCase -import io.kotest.property.Arb -import io.kotest.property.arbitrary.choice import io.kotest.property.checkAll import io.provenance.scope.loan.LoanScopeProperties.assetLoanKey import io.provenance.scope.loan.LoanScopeProperties.assetMismoKey @@ -46,8 +44,7 @@ class RecordLoanContractUnitTest : WordSpec({ exception shouldHaveViolationCount 3 exception.message shouldContainIgnoringCase "Asset must have valid ID" exception.message shouldContainIgnoringCase "Asset is missing type" - exception.message shouldContainIgnoringCase - "Exactly one of \"$assetLoanKey\" or \"$assetMismoKey\" must be a key in the input asset" + exception.message shouldContainIgnoringCase "\"$assetLoanKey\" must be a key in the input asset" } } } @@ -69,7 +66,7 @@ class RecordLoanContractUnitTest : WordSpec({ } } } - "given an input to an empty scope with a loan value not of the expected MISMO loan type" should { + "given an input to an empty scope with an invalid MISMO loan value and no Figure Tech loan type" should { "throw an appropriate exception" { checkAll(anyUuid, anyNonEmptyString) { randomAssetId, randomAssetType -> Asset.newBuilder().also { assetBuilder -> @@ -80,7 +77,8 @@ class RecordLoanContractUnitTest : WordSpec({ shouldThrow { recordContractWithEmptyScope.recordAsset(assetWithBadLoanType) }.let { exception -> - exception shouldHaveViolationCount 1 + exception shouldHaveViolationCount 2 + exception.message shouldContain "\"loan\" must be a key in the input asset" exception.message shouldContain "Could not unpack the input asset's \"$assetMismoKey\" as $MISMOLoanIdentifier" } } @@ -213,33 +211,6 @@ class RecordLoanContractUnitTest : WordSpec({ } } } - "given a MISMO loan input to an empty scope with a ULI of an invalid length" should { - "throw an appropriate exception" { - checkAll( - anyUuid, - anyNonEmptyString, - anyValidMismoLoan, - anyNonUliString, - ) { randomAssetId, randomType, randomLoan, randomInvalidUli -> - Asset.newBuilder().also { assetBuilder -> - assetBuilder.id = randomAssetId - assetBuilder.type = randomType - assetBuilder.putKv( - assetMismoKey, - randomLoan.toBuilder().also { loanBuilder -> - loanBuilder.uli = randomInvalidUli - }.build().toProtoAny() - ) - }.build().let { assetWithInvalidId -> - shouldThrow { - recordContractWithEmptyScope.recordAsset(assetWithInvalidId) - }.let { exception -> - exception.message shouldContainIgnoringCase "Loan ULI must be between 23 and 45 (inclusive) characters long" - } - } - } - } - } "given an input with invalid changes to the existing asset's ID" should { "throw an appropriate exception" { checkAll(anyUuid, anyUuid, anyUuid, anyNonEmptyString) { randomExistingUuid, randomNewUuid, randomLoanId, randomAssetType -> @@ -310,60 +281,6 @@ class RecordLoanContractUnitTest : WordSpec({ } } } - "given an input to an empty scope with more than one type of loan" should { - "throw an appropriate exception" { - checkAll( - anyUuid, - anyNonEmptyString, - anyValidFigureTechLoan, - anyValidMismoLoan - ) { randomAssetId, randomAssetType, randomFigureTechLoan, randomMismoLoan -> - shouldThrow { - recordContractWithEmptyScope.recordAsset( - Asset.newBuilder().also { assetBuilder -> - assetBuilder.id = randomAssetId - assetBuilder.type = randomAssetType - assetBuilder.putKv(assetLoanKey, randomFigureTechLoan.toProtoAny()) - assetBuilder.putKv(assetMismoKey, randomMismoLoan.toProtoAny()) - }.build() - ) - }.let { exception -> - exception.message shouldContain "Exactly one of \"$assetLoanKey\" or \"$assetMismoKey\" must be a key in the input asset" - } - } - } - } - "given an input with more than one type of loan to update an existing asset record" should { - "throw an appropriate exception" { - checkAll( - Arb.choice(anyValidAsset(), anyValidAsset()), - anyUuid, - anyNonEmptyString, - anyValidFigureTechLoan, - anyValidMismoLoan - ) { randomExistingAsset, randomAssetId, randomAssetType, randomFigureTechLoan, randomMismoLoan -> - shouldThrow { - RecordLoanContract( - existingAsset = randomExistingAsset, - // The rest of the parameters are not relevant to this test case - existingENote = ENote.getDefaultInstance(), - existingServicingData = ServicingData.getDefaultInstance(), - existingServicingRights = ServicingRights.getDefaultInstance(), - ) - recordContractWithEmptyScope.recordAsset( - Asset.newBuilder().also { assetBuilder -> - assetBuilder.id = randomAssetId - assetBuilder.type = randomAssetType - assetBuilder.putKv(assetLoanKey, randomFigureTechLoan.toProtoAny()) - assetBuilder.putKv(assetMismoKey, randomMismoLoan.toProtoAny()) - }.build() - ) - }.let { exception -> - exception.message shouldContain "Exactly one of \"$assetLoanKey\" or \"$assetMismoKey\" must be a key in the input asset" - } - } - } - } "given an input with a loan of a different type than the existing Figure Tech loan" should { "throw an appropriate exception" { checkAll(anyUuid, anyUuid, anyValidUli) { randomAssetId, randomLoanId, randomUli -> @@ -403,9 +320,14 @@ class RecordLoanContractUnitTest : WordSpec({ } } } - "given an input with a loan of a different type than the existing MISMO loan" should { + "given an input with a MISMO loan of a different type than the existing MISMO loan" should { "throw an appropriate exception" { - checkAll(anyUuid, anyUuid, anyValidUli) { randomAssetId, randomLoanId, randomUli -> + checkAll( + anyUuid, + anyUuid, + anyValidUli, + anyValidFigureTechLoan, + ) { randomAssetId, randomLoanId, randomUli, randomLoan -> val existingAsset = Asset.newBuilder().also { assetBuilder -> assetBuilder.id = randomAssetId // To mark the existing asset as being set assetBuilder.putKv( @@ -414,6 +336,7 @@ class RecordLoanContractUnitTest : WordSpec({ loanBuilder.uli = randomUli }.build().toProtoAny() ) + assetBuilder.putKv(assetLoanKey, randomLoan.toProtoAny()) }.build() val newAsset = Asset.newBuilder().also { assetBuilder -> assetBuilder.id = randomAssetId @@ -423,6 +346,7 @@ class RecordLoanContractUnitTest : WordSpec({ loanBuilder.id = randomLoanId }.build().toProtoAny() ) + assetBuilder.putKv(assetLoanKey, randomLoan.toProtoAny()) }.build() shouldThrow { RecordLoanContract( @@ -482,55 +406,7 @@ class RecordLoanContractUnitTest : WordSpec({ } } } - "given an input with invalid changes to the existing MISMO loan's ULI" should { - "throw an appropriate exception" { - checkAll( - anyValidUli, - anyValidUli, - anyUuid, - anyNonEmptyString, - anyValidMismoLoan, - ) { randomExistingUli, randomNewUli, randomAssetId, randomAssetType, randomLoan -> - val existingAsset = Asset.newBuilder().also { assetBuilder -> - assetBuilder.id = randomAssetId - assetBuilder.type = randomAssetType - assetBuilder.putKv( - assetMismoKey, - randomLoan.toBuilder().also { loanBuilder -> - loanBuilder.uli = randomExistingUli - }.build().toProtoAny() - ) - }.build() - val newAsset = Asset.newBuilder().also { assetBuilder -> - assetBuilder.id = randomAssetId - assetBuilder.type = randomAssetType - assetBuilder.putKv( - assetMismoKey, - randomLoan.toBuilder().also { loanBuilder -> - loanBuilder.uli = randomNewUli - }.build().toProtoAny() - ) - }.build() - if (randomExistingUli != randomNewUli) { - shouldThrow { - RecordLoanContract( - existingAsset = existingAsset, - // The rest of the parameters are not relevant to this test case - existingENote = ENote.getDefaultInstance(), - existingServicingData = ServicingData.getDefaultInstance(), - existingServicingRights = ServicingRights.getDefaultInstance(), - ).recordAsset( - newAsset = newAsset - ) - }.let { exception -> - exception shouldHaveViolationCount 1 - exception.message shouldContain "Cannot change loan ULI" - } - } - } - } - } - "given an input to an empty scope with a valid Figure Tech loan" should { + "given an input to an empty scope with a valid Figure Tech loan and no MISMO loan" should { "not throw an exception" { checkAll(anyUuid, anyNonEmptyString, anyValidFigureTechLoan) { randomAssetId, randomType, randomLoan -> recordContractWithEmptyScope.recordAsset( @@ -542,8 +418,7 @@ class RecordLoanContractUnitTest : WordSpec({ ).let { newAsset -> newAsset.id shouldBe randomAssetId newAsset.type shouldBe randomType - /* We don't use anyValidAsset() for this test case so that we can make the following check useful */ - newAsset.kvMap[assetLoanKey]!!.toFigureTechLoan() shouldBe randomLoan + newAsset.kvMap[assetLoanKey]?.toFigureTechLoan() shouldBe randomLoan } } } @@ -553,39 +428,74 @@ class RecordLoanContractUnitTest : WordSpec({ // TODO: Implement } } - "given a Figure Tech loan input to update an existing MISMO loan record" should { - "throw an appropriate exception" { - checkAll(anyValidAsset(), anyValidAsset()) { randomExistingAsset, randomNewAsset -> - shouldThrow { - RecordLoanContract( - existingAsset = randomExistingAsset, - // The rest of the parameters are not relevant to this test case - existingENote = ENote.getDefaultInstance(), - existingServicingData = ServicingData.getDefaultInstance(), - existingServicingRights = ServicingRights.getDefaultInstance(), - ).recordAsset( - newAsset = randomNewAsset - ) - }.let { exception -> - exception.message shouldContain "The input asset had key \"${assetLoanKey}\" but the existing asset did not" + "given an asset which removes the MISMO loan from an existing loan record" should { + "not throw an exception" { + checkAll( + anyValidAsset(hasMismoLoan = true), + ) { randomExistingAsset -> + val randomNewAsset = randomExistingAsset.toBuilder().also { newAssetBuilder -> + newAssetBuilder.removeKv(assetMismoKey) + }.build() + RecordLoanContract( + existingAsset = randomExistingAsset, + // The rest of the parameters are not relevant to this test case + existingENote = ENote.getDefaultInstance(), + existingServicingData = ServicingData.getDefaultInstance(), + existingServicingRights = ServicingRights.getDefaultInstance(), + ).recordAsset( + newAsset = randomNewAsset + ).let { resultingNewAsset -> + resultingNewAsset.id shouldBe randomExistingAsset.id + resultingNewAsset.type shouldBe randomExistingAsset.type + resultingNewAsset.kvMap[assetMismoKey] shouldBe null + } + } + } + } + "given an asset which adds a MISMO loan to an existing loan record" should { + "not throw an exception" { + checkAll( + anyValidAsset(hasMismoLoan = true), + ) { randomNewAsset -> + val randomExistingAsset = randomNewAsset.toBuilder().also { existingAssetBuilder -> + existingAssetBuilder.removeKv(assetMismoKey) + }.build() + RecordLoanContract( + existingAsset = randomExistingAsset, + // The rest of the parameters are not relevant to this test case + existingENote = ENote.getDefaultInstance(), + existingServicingData = ServicingData.getDefaultInstance(), + existingServicingRights = ServicingRights.getDefaultInstance(), + ).recordAsset( + newAsset = randomNewAsset + ).let { resultingNewAsset -> + resultingNewAsset.id shouldBe randomExistingAsset.id + resultingNewAsset.type shouldBe randomExistingAsset.type + resultingNewAsset.kvMap[assetMismoKey] shouldBe randomNewAsset.kvMap[assetMismoKey] } } } } - "given an input to an empty scope with a valid MISMO loan" should { + "given an input to an empty scope with a valid Figure Tech loan and valid MISMO loan" should { "not throw an exception" { - checkAll(anyUuid, anyNonEmptyString, anyValidMismoLoan) { randomAssetId, randomType, randomLoan -> + checkAll( + anyUuid, + anyNonEmptyString, + anyValidFigureTechLoan, + anyValidMismoLoan, + ) { randomAssetId, randomType, randomFigureTechLoan, randomMismoLoan -> recordContractWithEmptyScope.recordAsset( Asset.newBuilder().apply { id = randomAssetId type = randomType - putKv(assetMismoKey, randomLoan.toProtoAny()) + putKv(assetMismoKey, randomMismoLoan.toProtoAny()) + putKv(assetLoanKey, randomFigureTechLoan.toProtoAny()) }.build() ).let { newAsset -> newAsset.id shouldBe randomAssetId newAsset.type shouldBe randomType - /* We don't use anyValidAsset() for this test case so that we can make the following check useful */ - newAsset.kvMap[assetMismoKey]!!.toMISMOLoan() shouldBe randomLoan + newAsset.kvMap[assetLoanKey]?.toFigureTechLoan() shouldBe randomFigureTechLoan + newAsset.kvMap[assetMismoKey]?.toMISMOLoan() shouldBe randomMismoLoan } } } @@ -595,9 +505,17 @@ class RecordLoanContractUnitTest : WordSpec({ // TODO: Implement } } - "given a MISMO loan input to update an existing Figure Tech loan record" should { + "given an input with a MISMO loan but no Figure Tech loan to update an existing Figure Tech loan record" should { "throw an appropriate exception" { - checkAll(anyValidAsset(), anyValidAsset()) { randomExistingAsset, randomNewAsset -> + checkAll( + anyValidAsset(hasMismoLoan = true), + ) { randomBaseAsset -> + val randomExistingAsset = randomBaseAsset.toBuilder().also { existingAssetBuilder -> + existingAssetBuilder.removeKv(assetMismoKey) + }.build() + val randomNewAsset = randomBaseAsset.toBuilder().also { existingAssetBuilder -> + existingAssetBuilder.removeKv(assetLoanKey) + }.build() shouldThrow { RecordLoanContract( existingAsset = randomExistingAsset, @@ -609,7 +527,7 @@ class RecordLoanContractUnitTest : WordSpec({ newAsset = randomNewAsset ) }.let { exception -> - exception.message shouldContain "The input asset had key \"${assetMismoKey}\" but the existing asset did not" + exception.message shouldContain "\"${assetLoanKey}\" must be a key in the input asset" } } } diff --git a/contract/src/test/kotlin/io/provenance/scope/loan/test/KotestHelpers.kt b/contract/src/test/kotlin/io/provenance/scope/loan/test/KotestHelpers.kt index 5489fa0..92f2b24 100644 --- a/contract/src/test/kotlin/io/provenance/scope/loan/test/KotestHelpers.kt +++ b/contract/src/test/kotlin/io/provenance/scope/loan/test/KotestHelpers.kt @@ -1,7 +1,6 @@ package io.provenance.scope.loan.test import com.google.protobuf.InvalidProtocolBufferException -import com.google.protobuf.Message import com.google.protobuf.Timestamp import com.google.protobuf.util.Timestamps import io.dartinc.registry.v1beta1.Controller @@ -22,6 +21,7 @@ import io.kotest.property.arbitrary.boolean import io.kotest.property.arbitrary.double import io.kotest.property.arbitrary.filter import io.kotest.property.arbitrary.filterNot +import io.kotest.property.arbitrary.flatMap import io.kotest.property.arbitrary.int import io.kotest.property.arbitrary.list import io.kotest.property.arbitrary.localDate @@ -391,21 +391,37 @@ internal object MetadataAssetModelArbs { }.build() } /* Loan scope records */ - inline fun anyValidAsset(): Arb = - when (T::class) { - FigureTechLoan::class -> LoanScopeProperties.assetLoanKey to anyValidFigureTechLoan - MISMOLoanMetadata::class -> LoanScopeProperties.assetMismoKey to anyValidMismoLoan - else -> throw IllegalArgumentException("Must supply an expected loan type for an asset") - }.let { (loanKey, anyLoan) -> + fun anyValidAsset(): Arb = + Arb.boolean().flatMap { hasMismoLoan -> + anyValidAsset(hasMismoLoan = hasMismoLoan) + } + fun anyValidAsset( + hasMismoLoan: Boolean, + ): Arb = + if (hasMismoLoan) { + Arb.bind( + anyUuid, + PrimitiveArbs.anyNonEmptyString, + anyValidFigureTechLoan, + anyValidMismoLoan, + ) { assetId, assetType, figureTechLoan, mismoLoan -> + Asset.newBuilder().also { assetBuilder -> + assetBuilder.id = assetId + assetBuilder.type = assetType + assetBuilder.putKv(LoanScopeProperties.assetLoanKey, figureTechLoan.toProtoAny()) + assetBuilder.putKv(LoanScopeProperties.assetMismoKey, mismoLoan.toProtoAny()) + }.build() + } + } else { Arb.bind( anyUuid, PrimitiveArbs.anyNonEmptyString, - anyLoan, - ) { assetId, assetType, loan -> + anyValidFigureTechLoan, + ) { assetId, assetType, figureTechLoan -> Asset.newBuilder().also { assetBuilder -> assetBuilder.id = assetId assetBuilder.type = assetType - assetBuilder.putKv(loanKey, loan.toProtoAny()) + assetBuilder.putKv(LoanScopeProperties.assetLoanKey, figureTechLoan.toProtoAny()) }.build() } } @@ -488,14 +504,32 @@ internal object MetadataAssetModelArbs { }.build() } } - inline fun anyValidLoan( + fun anyValidLoan( + maxAssumptionCount: Int = 0, + maxModificationCount: Int = 0, + loanStateCount: Int = 3, + iterationCount: Int = 3, + loanDocumentCount: Int = 3, + ): Arb = Arb.boolean().flatMap { hasMismoLoan -> + anyValidLoan( + maxAssumptionCount = maxAssumptionCount, + maxModificationCount = maxModificationCount, + loanStateCount = loanStateCount, + iterationCount = iterationCount, + loanDocumentCount = loanDocumentCount, + hasMismoLoan = hasMismoLoan, + ) + } + + fun anyValidLoan( maxAssumptionCount: Int = 0, maxModificationCount: Int = 0, loanStateCount: Int = 3, iterationCount: Int = 3, loanDocumentCount: Int = 3, + hasMismoLoan: Boolean, ): Arb = Arb.bind( - anyValidAsset(), + anyValidAsset(hasMismoLoan = hasMismoLoan), anyValidENote(maxAssumptionCount = maxAssumptionCount, maxModificationCount = maxModificationCount), anyValidServicingRights, anyValidServicingData(loanStateAndDocumentCount = loanStateCount), diff --git a/contract/src/test/kotlin/io/provenance/scope/loan/test/TestDataGenerators.kt b/contract/src/test/kotlin/io/provenance/scope/loan/test/TestDataGenerators.kt index fdebe7a..edf4023 100644 --- a/contract/src/test/kotlin/io/provenance/scope/loan/test/TestDataGenerators.kt +++ b/contract/src/test/kotlin/io/provenance/scope/loan/test/TestDataGenerators.kt @@ -16,9 +16,7 @@ import io.provenance.scope.loan.test.MetadataAssetModelArbs.anyValidLoanDocument import io.provenance.scope.loan.test.MetadataAssetModelArbs.anyValidServicingData import io.provenance.scope.loan.test.MetadataAssetModelArbs.anyValidServicingRights import io.provenance.scope.loan.test.MetadataAssetModelArbs.anyValidValidationRecord -import tech.figure.loan.v1beta1.MISMOLoanMetadata import tech.figure.proto.util.toProtoAny -import tech.figure.loan.v1beta1.Loan as FigureTechLoan @Ignored internal class TestDataGenerators : WordSpec({ @@ -30,8 +28,8 @@ internal class TestDataGenerators : WordSpec({ val randomSource = RandomSource.default() /* JSON generators */ "KotestHelpers" should { - "be able to generate a random fully populated Figure Tech loan scope" { - anyValidLoan().next(randomSource).let { randomLoanPackage -> + "be able to generate a random fully populated loan scope without a MISMO loan" { + anyValidLoan(hasMismoLoan = false).next(randomSource).let { randomLoanPackage -> println( mapper.writeValueAsString( mapOf( @@ -46,8 +44,8 @@ internal class TestDataGenerators : WordSpec({ ) } } - "be able to generate a random fully populated MISMO loan scope" { - anyValidLoan().next(randomSource).let { randomLoanPackage -> + "be able to generate a random fully populated loan scope with a MISMO loan" { + anyValidLoan(hasMismoLoan = true).next(randomSource).let { randomLoanPackage -> println( mapper.writeValueAsString( mapOf( @@ -64,12 +62,12 @@ internal class TestDataGenerators : WordSpec({ } "be able to generate a random asset for a Figure Tech loan" { println( - mapper.writeValueAsString(anyValidAsset().next(randomSource)) + mapper.writeValueAsString(anyValidAsset(hasMismoLoan = false).next(randomSource)) ) } - "be able to generate a random asset for a MISMO loan" { + "be able to generate a random asset for a Figure Tech loan with a MISMO loan" { println( - mapper.writeValueAsString(anyValidAsset().next(randomSource)) + mapper.writeValueAsString(anyValidAsset(hasMismoLoan = true).next(randomSource)) ) } "be able to generate a random eNote" {