Skip to content

Commit 2629101

Browse files
committed
Add batch ULI validation tests
1 parent a9fd899 commit 2629101

File tree

6 files changed

+40
-42
lines changed

6 files changed

+40
-42
lines changed

api/src/main/scala/hmda/api/http/public/PublicHttpApi.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ trait PublicHttpApi extends PublicLarHttpApi with HmdaCustomDirectives with ApiE
5555
fileUpload("file") {
5656
case (_, byteSource) =>
5757
val validatedF = processUliFile(byteSource).runWith(Sink.seq)
58-
5958
onComplete(validatedF) {
6059
case Success(validated) =>
6160
complete(ToResponseMarshallable(ULIBatchValidatedResponse(validated)))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package hmda.api.http
2+
3+
import akka.http.scaladsl.model.{ ContentTypes, HttpEntity, Multipart }
4+
5+
trait FileUploadUtils {
6+
def multiPartFile(contents: String, fileName: String) =
7+
Multipart.FormData(Multipart.FormData.BodyPart.Strict(
8+
"file",
9+
HttpEntity(ContentTypes.`text/plain(UTF-8)`, contents),
10+
Map("filename" -> fileName)
11+
))
12+
}

api/src/test/scala/hmda/api/http/InstitutionHttpSpec.scala

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import scala.concurrent.duration._
2323
import akka.pattern.ask
2424
import scala.concurrent._
2525

26-
trait InstitutionHttpSpec extends MustMatchers with BeforeAndAfterAll with RequestHeaderUtils with InstitutionsHttpApi with ScalatestRouteTest { suite: Suite =>
26+
trait InstitutionHttpSpec extends MustMatchers with BeforeAndAfterAll with RequestHeaderUtils with InstitutionsHttpApi with FileUploadUtils with ScalatestRouteTest { suite: Suite =>
2727
val configuration: Config = ConfigFactory.load()
2828

2929
val validationStats = ValidationStats.createValidationStats(system)
@@ -55,11 +55,4 @@ trait InstitutionHttpSpec extends MustMatchers with BeforeAndAfterAll with Reque
5555
FileUtils.deleteRecursively(snapshotStore)
5656
}
5757

58-
def multiPartFile(contents: String, fileName: String) =
59-
Multipart.FormData(Multipart.FormData.BodyPart.Strict(
60-
"file",
61-
HttpEntity(ContentTypes.`text/plain(UTF-8)`, contents),
62-
Map("filename" -> fileName)
63-
))
64-
6558
}

api/src/test/scala/hmda/api/http/public/PublicHttpApiSpec.scala

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@ import akka.http.scaladsl.model.StatusCodes
55
import akka.http.scaladsl.testkit.ScalatestRouteTest
66
import akka.util.Timeout
77
import hmda.api.RequestHeaderUtils
8-
import hmda.api.model.public.ULIModel.{ Loan, ULI, ULICheck, ULIValidated }
8+
import hmda.api.model.public.ULIModel._
99
import hmda.api.protocol.public.ULIProtocol
1010
import hmda.model.fi.lar.LarGenerators
1111
import hmda.query.repository.filing.LarConverter._
1212
import org.scalatest.{ BeforeAndAfterAll, MustMatchers, WordSpec }
1313
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
14+
import hmda.api.http.FileUploadUtils
1415

1516
import scala.concurrent.duration._
1617

1718
class PublicHttpApiSpec extends WordSpec with MustMatchers with BeforeAndAfterAll
18-
with ScalatestRouteTest with RequestHeaderUtils with PublicHttpApi with LarGenerators with ULIProtocol {
19+
with ScalatestRouteTest with RequestHeaderUtils with PublicHttpApi with FileUploadUtils with LarGenerators with ULIProtocol {
1920

2021
override val log: LoggingAdapter = NoLogging
2122
implicit val ec = system.dispatcher
@@ -27,6 +28,10 @@ class PublicHttpApiSpec extends WordSpec with MustMatchers with BeforeAndAfterAl
2728
val l1 = toLoanApplicationRegisterQuery(sampleLar).copy(period = p, institutionId = "0")
2829
val l2 = toLoanApplicationRegisterQuery(sampleLar).copy(period = p, institutionId = "0")
2930

31+
val uliTxt = "10Cx939c5543TqA1144M999143X10\n" +
32+
"10Bx939c5543TqA1144M999143X38\n" +
33+
"10Bx939c5543TqA1144M999133X38\n"
34+
3035
"Modified LAR Http API" must {
3136
"return list of modified LARs in proper format" in {
3237
Get("/institutions/0/filings/2017/lar") ~> publicHttpRoutes ~> check {
@@ -39,6 +44,7 @@ class PublicHttpApiSpec extends WordSpec with MustMatchers with BeforeAndAfterAl
3944
}
4045

4146
"ULI API" must {
47+
val uliFile = multiPartFile(uliTxt, "ulis.txt")
4248
val loanId = "10Bx939c5543TqA1144M999143X"
4349
val checkDigit = 38
4450
val uli = "10Bx939c5543TqA1144M999143X" + checkDigit
@@ -55,6 +61,25 @@ class PublicHttpApiSpec extends WordSpec with MustMatchers with BeforeAndAfterAl
5561
responseAs[ULIValidated] mustBe ULIValidated(true)
5662
}
5763
}
64+
"validate a file of ULIs and return csv" in {
65+
Post("/uli/validate/csv", uliFile) ~> publicHttpRoutes ~> check {
66+
status mustBe StatusCodes.OK
67+
val csv = responseAs[String]
68+
csv must include("10Cx939c5543TqA1144M999143X10,true")
69+
csv must include("10Bx939c5543TqA1144M999143X38,true")
70+
csv must include("10Bx939c5543TqA1144M999133X38,false")
71+
}
72+
}
73+
"validate a file of ULIs" in {
74+
Post("/uli/validate", uliFile) ~> publicHttpRoutes ~> check {
75+
status mustBe StatusCodes.OK
76+
responseAs[ULIBatchValidatedResponse].ulis mustBe Seq(
77+
ULIBatchValidated("10Cx939c5543TqA1144M999143X10", true),
78+
ULIBatchValidated("10Bx939c5543TqA1144M999143X38", true),
79+
ULIBatchValidated("10Bx939c5543TqA1144M999133X38", false)
80+
)
81+
}
82+
}
5883
}
5984

6085
}

validation/src/main/scala/hmda/validation/engine/lar/ULI.scala

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package hmda.validation.engine.lar
22

3-
import akka.NotUsed
4-
import akka.stream.scaladsl.Source
5-
63
//See https://www.consumerfinance.gov/eregulations/1003-C/2015-26607_20180101#1003-C-1
74

85
object ULI {
@@ -61,18 +58,8 @@ object ULI {
6158
loanId + checkDigit(loanId).toString()
6259
}
6360

64-
def checkDigitBatch(loanIdSource: Source[String, NotUsed]): Source[(String, BigInt), NotUsed] = {
65-
loanIdSource
66-
.map(loanId => (loanId, checkDigit(loanId)))
67-
}
68-
6961
def validateULI(uli: String): Boolean = {
7062
calculateMod(BigInt(convert(uli))) == 1
7163
}
7264

73-
def validateULIBatch(uliSource: Source[String, NotUsed]): Source[(String, Boolean), NotUsed] = {
74-
uliSource
75-
.map(uli => (uli, validateULI(uli)))
76-
}
77-
7865
}

validation/src/test/scala/hmda/validation/engine/lar/ULISpec.scala

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -34,23 +34,5 @@ class ULISpec extends AsyncWordSpec with MustMatchers with BeforeAndAfterAll {
3434
ULI.validateULI(validULI2) mustBe true
3535
ULI.validateULI(invalidULI) mustBe false
3636
}
37-
"produce valid check digits in batch" in {
38-
val loanIt = List(loan1, loan2).toIterator
39-
val loanSource = Source.fromIterator(() => loanIt)
40-
val checkDigitF = ULI.checkDigitBatch(loanSource).runWith(Sink.seq)
41-
checkDigitF.map { checkDigit =>
42-
checkDigit.head._2 mustBe 38
43-
checkDigit.tail.head._2 mustBe 10
44-
}
45-
}
46-
"Validate a list of ULIs" in {
47-
val uliIt = List(validULI1, invalidULI).toIterator
48-
val uliSource = Source.fromIterator(() => uliIt)
49-
val validatedF = ULI.validateULIBatch(uliSource).runWith(Sink.seq)
50-
validatedF.map { validated =>
51-
validated.head._2 mustBe true
52-
validated.tail.head._2 mustBe false
53-
}
54-
}
5537
}
5638
}

0 commit comments

Comments
 (0)