Skip to content

Commit

Permalink
https://github.com/AtlasOfLivingAustralia/data-management/issues/76:
Browse files Browse the repository at this point in the history
Changes to AssertionIntegrationTest and AssertionCodeTest cases and convertAssertionsToMap
  • Loading branch information
patkyn committed Jul 26, 2016
1 parent 67e331f commit d391d96
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 46 deletions.
48 changes: 34 additions & 14 deletions src/main/scala/au/org/ala/biocache/dao/OccurrenceDAOImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ class OccurrenceDAOImpl extends OccurrenceDAO {
val properties = FullRecordMapper.fullRecord2Map(fullRecord, version)

if (!assertions.isEmpty) {
properties ++= convertAssertionsToMap(rowKey,assertions.get, fullRecord.userVerified)
properties ++= convertAssertionsToMap(rowKey,assertions.get)
updateSystemAssertions(rowKey, assertions.get)
}

Expand Down Expand Up @@ -586,7 +586,7 @@ class OccurrenceDAOImpl extends OccurrenceDAO {
//only add the assertions if they are different OR the properties to persist contain more than the last modified time stamp
if((oldRecord.assertions.toSet != newRecord.assertions.toSet) || !(propertiesToPersist.size == 1 && propertiesToPersist.getOrElse(timeCol, "") != "")){
//only add the assertions if they have changed since the last time or the number of records to persist >1
propertiesToPersist ++= convertAssertionsToMap(rowKey,assertions.get,newRecord.userVerified)
propertiesToPersist ++= convertAssertionsToMap(rowKey,assertions.get)
updateSystemAssertions(rowKey, assertions.get)
}
}
Expand Down Expand Up @@ -643,7 +643,7 @@ class OccurrenceDAOImpl extends OccurrenceDAO {
//only add the assertions if they are different OR the properties to persist contain more than the last modified time stamp
if ((oldRecord.assertions.toSet != newRecord.assertions.toSet) || !(propertiesToPersist.size == 1 && propertiesToPersist.getOrElse(timeCol, "") != "")) {
//only add the assertions if they have changed since the last time or the number of records to persist >1
propertiesToPersist ++= convertAssertionsToMap(rowKey, assertions.get, newRecord.userVerified)
propertiesToPersist ++= convertAssertionsToMap(rowKey, assertions.get)
updateSystemAssertions(rowKey, assertions.get)
}
}
Expand Down Expand Up @@ -671,20 +671,38 @@ class OccurrenceDAOImpl extends OccurrenceDAO {
/**
* Convert the assertions to a map
*/
def convertAssertionsToMap(rowKey:String, systemAssertions: Map[String,Array[QualityAssertion]], verified:Boolean): Map[String, String] = {
def convertAssertionsToMap(rowKey:String, systemAssertions: Map[String,Array[QualityAssertion]]): Map[String, String] = {
//if supplied, update the assertions
val properties = new collection.mutable.ListMap[String, String]

val userAssertions = getUserAssertions(rowKey)

// Updating system assertion, pass in false
val (userAssertionStatus, trueUserAssertions) = getCombinedUserStatus(false, userAssertions)

val verified = if (userAssertionStatus == AssertionStatus.QA_VERIFIED || userAssertionStatus == AssertionStatus.QA_CORRECTED) true else false

val falseUserAssertions = userAssertions.filter(qa => qa.code != AssertionCodes.VERIFIED.code &&
AssertionStatus.isUserAssertionType(qa.qaStatus) &&
!trueUserAssertions.exists(a => a.code == qa.code))

if(verified){
//kosher fields are always set to true for verified BUT we still want to store and report the QA's that failed
//kosher fields are always set to true for verified BUT we still want to store and report the QA's that failed
var listErrorCodes = new ArrayBuffer[Int]()
trueUserAssertions.foreach { qa: QualityAssertion => listErrorCodes.append(qa.code) }

if (AssertionCodes.isGeospatiallyKosher(listErrorCodes.toArray)) {
properties += (FullRecordMapper.geospatialDecisionColumn -> "true")
}
if (AssertionCodes.isTaxonomicallyKosher(listErrorCodes.toArray)) {
properties += (FullRecordMapper.taxonomicDecisionColumn -> "true")
}

}

val userAssertions = getUserAssertions(rowKey)
val falseUserAssertions = userAssertions.filter(qa => qa.qaStatus == 1)//userAssertions.filter(a => !a.problemAsserted)
// val falseUserAssertions = userAssertions.filter(qa => qa.qaStatus == 1)//userAssertions.filter(a => !a.problemAsserted)
//true user assertions are assertions that have not been proven false by another user
val trueUserAssertions = userAssertions.filter(a => a.qaStatus == 0 && !doesListContainCode(falseUserAssertions,a.code))
// val trueUserAssertions = userAssertions.filter(a => a.qaStatus == 0 && !doesListContainCode(falseUserAssertions,a.code))

//for each qa type get the list of QA's that failed
val assertionsDeleted = ListBuffer[QualityAssertion]() // stores the assertions that should not be considered for the kosher fields
Expand All @@ -711,10 +729,8 @@ class OccurrenceDAOImpl extends OccurrenceDAO {
case "event" => a.code >= AssertionCodes.temporalBounds._1 && a.code < AssertionCodes.temporalBounds._2
case _ => false
})
val extraAssertions = ListBuffer[QualityAssertion]()
ua2Add.foreach(qa =>if(!failedass.contains(qa.code)){
failedass.add(qa.code)
extraAssertions += qa
})

properties += (FullRecordMapper.markAsQualityAssertion(name) -> Json.toJSONWithGeneric(failedass.toList))
Expand Down Expand Up @@ -955,7 +971,7 @@ class OccurrenceDAOImpl extends OccurrenceDAO {
* qaStatus: AssertionStatus.QA_OPEN_ISSUE, AssertionStatus.QA_VERIFIED, AssertionStatus:QA_CORRECTED
*
*/
private def getCombinedUserStatus(currentAssertion: QualityAssertion, userAssertions: List[QualityAssertion]): (Int, ArrayBuffer[QualityAssertion]) = {
private def getCombinedUserStatus(bVerified: Boolean, userAssertions: List[QualityAssertion]): (Int, ArrayBuffer[QualityAssertion]) = {

// val openAssertions = new ArrayBuffer[QualityAssertion]()

Expand Down Expand Up @@ -983,7 +999,8 @@ class OccurrenceDAOImpl extends OccurrenceDAO {

// However if it's verified assertion, default to latest verified qa Status, which could be Verified, Corrected or Open Issue
// Use maxBy referenceRowKey rather than currentAssertion in case currentAssertion is the record that is to be deleted
if (AssertionCodes.isVerified(currentAssertion)) {
// if (AssertionCodes.isVerified(currentAssertion)) {
if (bVerified) {
if (!latestVerifiedList.isEmpty) {
userAssertionStatus = latestVerifiedList.maxBy(_.referenceRowKey).qaStatus
} else {
Expand Down Expand Up @@ -1026,7 +1043,9 @@ class OccurrenceDAOImpl extends OccurrenceDAO {

logger.debug("Updating the assertion status for : " + rowKey)

val (userAssertionStatus, remainingAssertions) = getCombinedUserStatus(assertion, userAssertions)
val bVerified = AssertionCodes.isVerified(assertion)

val (userAssertionStatus, remainingAssertions) = getCombinedUserStatus(bVerified, userAssertions)

// default to the assertion which is to be evaluated
var actualAssertion = assertion
Expand Down Expand Up @@ -1102,7 +1121,8 @@ class OccurrenceDAOImpl extends OccurrenceDAO {

if (AssertionCodes.isGeospatiallyKosher(listErrorCodes.toArray)) {
properties += (FullRecordMapper.geospatialDecisionColumn -> "true")
} else if (AssertionCodes.isTaxonomicallyKosher(listErrorCodes.toArray)) {
}
if (AssertionCodes.isTaxonomicallyKosher(listErrorCodes.toArray)) {
properties += (FullRecordMapper.taxonomicDecisionColumn -> "true")
}
} else if(phase == FullRecordMapper.geospatialQa){
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,8 @@ object QualityAssertion {
val uuid = UUID.randomUUID().toString
new QualityAssertion(uuid,null, null, assertionCode,null,null,qaStatus,null,null,null,null,null,null,null,null,new Date())
}
def apply(recUuid: String, errorCode:ErrorCode, qaStatus:Int, relatedUuid: String) ={
var uuid = recUuid
if (uuid.equals("")) {
uuid = UUID.randomUUID().toString
}
def apply(errorCode:ErrorCode, relatedUuid: String, qaStatus:Int) = {
val uuid = UUID.randomUUID().toString
new QualityAssertion(uuid,null, errorCode.name, errorCode.code,null,relatedUuid,qaStatus,null,null,null,null,null,null,null,null,new Date())
}

Expand Down
80 changes: 66 additions & 14 deletions src/test/scala/au/org/ala/biocache/AssertionCodeTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,59 @@ class AssertionCodeTest extends ConfigFunSuite {
val rowKey3 = "test3"
val uuid = "uuid"
val occurrenceDAO = Config.occurrenceDAO

test("Test isGeospatiallyKosher"){
val expectTrue1 = AssertionCodes.isGeospatiallyKosher(Array(20000))
expectResult(true){expectTrue1}

val expectTrue2 = AssertionCodes.isGeospatiallyKosher(Array(1))
expectResult(true){expectTrue2}

val expectFalse = AssertionCodes.isGeospatiallyKosher(Array(0, 1))
expectResult(false){expectFalse}

val expectTrueOld1 = Array(20000).filter(qa=> {
val code = AssertionCodes.geospatialCodes.find(c => c.code == qa)
!code.isEmpty && code.get.isFatal
}).isEmpty
expectResult(true){expectTrueOld1}

val expectTrueOld2 = Array(1).filter(qa=> {
val code = AssertionCodes.geospatialCodes.find(c => c.code == qa)
!code.isEmpty && code.get.isFatal
}).isEmpty
expectResult(true){expectTrueOld2}

val expectFalseOld = Array(0, 1).filter(qa=> {
val code = AssertionCodes.geospatialCodes.find(c => c.code == qa)
!code.isEmpty && code.get.isFatal
}).isEmpty
expectResult(false){expectFalseOld}

}

test("Test isTaxonomicallyKosher"){
val expectTrue1 = AssertionCodes.isTaxonomicallyKosher(Array(0))
expectResult(true){expectTrue1}

val expectTrue2 = AssertionCodes.isTaxonomicallyKosher(Array(10000))
expectResult(true){expectTrue2}

val expectTrueOld1 = Array(0).filter(qa=> {
val code = AssertionCodes.taxonomicCodes.find(c => c.code == qa)
!code.isEmpty && code.get.isFatal
}).isEmpty
expectResult(true){expectTrueOld1}

val expectTrueOld2 = Array(10000).filter(qa=> {
val code = AssertionCodes.taxonomicCodes.find(c => c.code == qa)
!code.isEmpty && code.get.isFatal
}).isEmpty
expectResult(true){expectTrueOld2}

}


test("Test the geospatially kosher test") {

val assertions1 = Array(QualityAssertion(AssertionCodes.GEOSPATIAL_ISSUE), QualityAssertion(AssertionCodes.INVERTED_COORDINATES))
Expand Down Expand Up @@ -48,7 +101,7 @@ class AssertionCodeTest extends ConfigFunSuite {
processed.location.decimalLongitude = "123.123"
processed.rowKey = rowKey
processed.uuid = uuid
val assertions = Some(Map("loc" -> Array(QualityAssertion("123", AssertionCodes.GEOSPATIAL_ISSUE, 0, ""))))
val assertions = Some(Map("loc" -> Array(QualityAssertion(AssertionCodes.GEOSPATIAL_ISSUE))))
occurrenceDAO.updateOccurrence(rowKey, processed, assertions, Versions.PROCESSED)
expectResult(1) {
occurrenceDAO.getSystemAssertions(rowKey).size
Expand All @@ -63,8 +116,7 @@ class AssertionCodeTest extends ConfigFunSuite {
}
//println(Config.persistenceManager)
//now have a false user assertion counteract this one
val qa = QualityAssertion("", AssertionCodes.VERIFIED, AssertionStatus.QA_VERIFIED, "123")

val qa = QualityAssertion(AssertionCodes.VERIFIED, "system", AssertionStatus.QA_VERIFIED)
// val qa = QualityAssertion(AssertionCodes.GEOSPATIAL_ISSUE, false)
qa.comment = "Overrride the system assertion"
qa.userId = "Natasha.Carter@csiro.au"
Expand All @@ -85,7 +137,7 @@ class AssertionCodeTest extends ConfigFunSuite {
* A false user assertion overrides all true user or system assertions (for the same code)
*/
test("Single false User Assertion takes precedence") {
val qa1 = QualityAssertion("222", AssertionCodes.TAXONOMIC_ISSUE, 0, "")
val qa1 = QualityAssertion(AssertionCodes.TAXONOMIC_ISSUE, "", AssertionStatus.QA_UNCONFIRMED)
qa1.comment = "True user assertion"
qa1.userId = "Natasha.Carter@csiro.au"
qa1.userDisplayName = "Natasha Carter"
Expand All @@ -100,7 +152,7 @@ class AssertionCodeTest extends ConfigFunSuite {
record.get.assertions.contains("taxonomicIssue")
}
// val qa2 = QualityAssertion(AssertionCodes.TAXONOMIC_ISSUE, false)
val qa2 = QualityAssertion("", AssertionCodes.VERIFIED, AssertionStatus.QA_VERIFIED, "222")
val qa2 = QualityAssertion(AssertionCodes.VERIFIED, qa1.uuid, AssertionStatus.QA_VERIFIED)
qa2.comment = "False user assertion to override"
qa2.userId = "Natasha.Carter2@csiro.au"
qa2.userDisplayName = "Natasha Carter"
Expand All @@ -120,7 +172,7 @@ class AssertionCodeTest extends ConfigFunSuite {
*/
test("User Assertions checked during system assertions update") {
//add user asssertion
val qa1 = QualityAssertion(AssertionCodes.ID_PRE_OCCURRENCE, true)
val qa1 = QualityAssertion(AssertionCodes.ID_PRE_OCCURRENCE, "", AssertionStatus.QA_UNCONFIRMED)
qa1.comment = "Tests user assertion is still applied after system assertions updated"
qa1.userId = "Natasha.Carter@csiro.au"
qa1.userDisplayName = "Natasha Carter"
Expand All @@ -137,7 +189,7 @@ class AssertionCodeTest extends ConfigFunSuite {
record.get.assertions.contains("idPreOccurrence")
}
//println(Config.persistenceManager)
val qa2 = QualityAssertion(AssertionCodes.ID_PRE_OCCURRENCE, false)
val qa2 = QualityAssertion(AssertionCodes.VERIFIED, qa1.uuid, AssertionStatus.QA_VERIFIED)
qa2.comment = "False value overrides"
qa2.userId = "Natasha.Carter2@csiro.au"
qa2.userDisplayName = "Natasha Carter"
Expand Down Expand Up @@ -169,7 +221,7 @@ class AssertionCodeTest extends ConfigFunSuite {
val record = occurrenceDAO.getByRowKey(rowKey2)
record.get.geospatiallyKosher
}
val vr = QualityAssertion(AssertionCodes.VERIFIED, true)
val vr = QualityAssertion(AssertionCodes.VERIFIED, "system", AssertionStatus.QA_VERIFIED)
vr.comment = "This record is verified"
vr.userId = "Natasha.Carter@csiro.au"
vr.userDisplayName = "Natasha Carter"
Expand All @@ -186,7 +238,7 @@ class AssertionCodeTest extends ConfigFunSuite {
expectResult(true) {
val record = occurrenceDAO.getByRowKey(rowKey2)
//println(record.get.assertions.toList)
record.get.geospatiallyKosher && record.get.assertions.contains("userVerified")
record.get.geospatiallyKosher //&& record.get.assertions.contains("userVerified")

}
//test that record 2 only reports back the 1 user assertion
Expand All @@ -204,16 +256,16 @@ class AssertionCodeTest extends ConfigFunSuite {
processed.rowKey = rowKey3
processed.uuid = uuid
occurrenceDAO.updateOccurrence(rowKey3, processed, None, Versions.PROCESSED)
val qa1 = QualityAssertion(AssertionCodes.TAXONOMIC_ISSUE, true)
val qa1 = QualityAssertion(AssertionCodes.TAXONOMIC_ISSUE, "", AssertionStatus.QA_UNCONFIRMED)
qa1.userId = "Natasha.Carter@csiro.au"
qa1.userDisplayName = "Natasha Carter"
occurrenceDAO.addUserAssertion(rowKey3, qa1)
expectResult("true") {
pm.get(rowKey3, "occ", FullRecordMapper.userQualityAssertionColumn).get
expectResult(AssertionStatus.QA_UNCONFIRMED) {
Integer.parseInt(pm.get(rowKey3, "occ", FullRecordMapper.userAssertionStatusColumn).get)
}
occurrenceDAO.deleteUserAssertion(rowKey3, qa1.uuid)
expectResult("false") {
pm.get(rowKey3, "occ", FullRecordMapper.userQualityAssertionColumn).get
expectResult(AssertionStatus.QA_NONE) {
Integer.parseInt(pm.get(rowKey3, "occ", FullRecordMapper.userAssertionStatusColumn).get)
}
}

Expand Down
Loading

0 comments on commit d391d96

Please sign in to comment.