From c2be65ecaabcab1f8fcf2dd1ad77a9246ce868f0 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 11 Apr 2023 10:36:06 +1000 Subject: [PATCH 01/20] Undid changes to separate mongo tests. #826 --- build.gradle | 22 +++---------------- .../au/org/ala/ecodata/ManagementUnit.groovy | 16 +++++--------- .../au/org/ala/ecodata/CommonService.groovy | 4 ++++ .../au/org/ala/ecodata/GormMongoUtil.groovy | 13 +++-------- .../ala/ecodata/BulkImportServiceSpec.groovy | 4 +--- .../org/ala/ecodata/SiteControllerSpec.groovy | 2 -- 6 files changed, 16 insertions(+), 45 deletions(-) diff --git a/build.gradle b/build.gradle index efe94477a..2ac2960d0 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,7 @@ plugins { id 'jacoco' } -version "4.1-biocollect-6.5-SNAPSHOT" +version "4.1-SNAPSHOT" group "au.org.ala" description "Ecodata" @@ -159,9 +159,6 @@ dependencies { testImplementation "com.squareup.retrofit2:retrofit-mock:2.4.0" - // This is needed to support test execution based on @Tag - testImplementation "org.spockframework:spock-core:2.2-groovy-3.0" - runtimeOnly "org.slf4j:jul-to-slf4j:1.7.7" runtimeOnly "org.hsqldb:hsqldb:2.3.1" } @@ -192,30 +189,17 @@ tasks.withType(GroovyCompile) { } tasks.withType(Test) { - useJUnitPlatform() { - excludeTags("mongo") - } - + useJUnitPlatform() } tasks.withType(Test) { testLogging { events "passed", "skipped", "failed" exceptionFormat 'full' + showStandardStreams true } } -tasks.register("mongoSpecTests", Test) { - useJUnitPlatform { - includeTags "mongo" - } - systemProperty "grails.env", "test" -} - -test { - dependsOn "mongoSpecTests" -} - assets { minifyJs = true minifyCss = true diff --git a/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy b/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy index 3c6cc9e21..b10da857c 100644 --- a/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy +++ b/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy @@ -110,19 +110,13 @@ class ManagementUnit { def getReportConfig() { def reportConfig = [] if(config) { - if(config.managementUnitReports) { - config.managementUnitReports.each { - it.report = "managementUnitReport" - } - reportConfig.addAll(config.managementUnitReports) + reportConfig += config.managementUnitReports?.collect { + [:] + it + [report:"managementUnitReport"] } - if(config.projectReports) { - config.projectReports.each { - it.report = "projectReport" - } - reportConfig.addAll(config.projectReports) + reportConfig += config.projectReports?.collect { + [:] + it + [report:"projectReport"] } - } + } return reportConfig } diff --git a/grails-app/services/au/org/ala/ecodata/CommonService.groovy b/grails-app/services/au/org/ala/ecodata/CommonService.groovy index 4ad8d1710..bda4fe2af 100644 --- a/grails-app/services/au/org/ala/ecodata/CommonService.groovy +++ b/grails-app/services/au/org/ala/ecodata/CommonService.groovy @@ -11,6 +11,7 @@ class CommonService { def messageSource /** + * Deprecated: Use grails/spring dataBinding instead. * Updates all properties other than 'id' and converts date strings to BSON dates. * * Note that dates are assumed to be ISO8601 in UTC with no millisecs @@ -21,6 +22,7 @@ class CommonService { * @param o the domain instance * @param props the properties to use */ + @Deprecated def updateProperties(o, props, boolean overrideUpdateDate = false) throws Exception{ assert grailsApplication def domainDescriptor = grailsApplication.getArtefact(DomainClassArtefactHandler.TYPE, @@ -79,10 +81,12 @@ class CommonService { } /** + * Deprecated access of the dbo property is deprecated in GORM for mongo * Converts the domain object into a map of properties with no additions. * @param o a domain instance * @return map of properties */ + @Deprecated def toBareMap(o) { def mapOfProperties = GormMongoUtil.extractDboProperties(o.getProperty("dbo")) // def mapOfProperties = dbo.toMap() diff --git a/src/main/groovy/au/org/ala/ecodata/GormMongoUtil.groovy b/src/main/groovy/au/org/ala/ecodata/GormMongoUtil.groovy index aadb33064..74d1bfe3e 100644 --- a/src/main/groovy/au/org/ala/ecodata/GormMongoUtil.groovy +++ b/src/main/groovy/au/org/ala/ecodata/GormMongoUtil.groovy @@ -1,27 +1,20 @@ package au.org.ala.ecodata import grails.gorm.DetachedCriteria +import org.grails.datastore.gorm.schemaless.DynamicAttributes import org.springframework.validation.Errors class GormMongoUtil { // convert object to map + @Deprecated + /** The dbo property of domain objects is deprecated */ static Map extractDboProperties(obj) { obj.collectEntries { field -> [field.key, field.value] } } - static Map extractDboPropertiesWithDateConversion(obj) { - obj.collectEntries { field -> - def value = field.value - if (field.value instanceof Date) { - value = DateUtil.format(field.value) - } - [field.key, value] - } - } - // Deep Prune a hash of all empty [:], [] preserving false and other invalid values static Map deepPrune(Map map) { map.collectEntries { k, v -> diff --git a/src/test/groovy/au/org/ala/ecodata/BulkImportServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/BulkImportServiceSpec.groovy index 2ea3ddf18..8cfb1e606 100644 --- a/src/test/groovy/au/org/ala/ecodata/BulkImportServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/BulkImportServiceSpec.groovy @@ -3,9 +3,8 @@ package au.org.ala.ecodata import au.org.ala.web.AuthService import grails.test.mongodb.MongoSpec import grails.testing.services.ServiceUnitTest -import spock.lang.Tag -@Tag("mongo") + class BulkImportServiceSpec extends MongoSpec implements ServiceUnitTest { def authService def setup() { @@ -25,7 +24,6 @@ class BulkImportServiceSpec extends MongoSpec implements ServiceUnitTest { SiteService siteService = Stub(SiteService); From 3235888845ea3317bd8fa882353efdb78f3d49c9 Mon Sep 17 00:00:00 2001 From: temi Date: Tue, 11 Apr 2023 10:23:47 +1000 Subject: [PATCH 02/20] refactored code to not use toBareMap function --- .../au/org/ala/ecodata/BulkImport.groovy | 20 +++++++++++++++++++ .../org/ala/ecodata/BulkImportService.groovy | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/grails-app/domain/au/org/ala/ecodata/BulkImport.groovy b/grails-app/domain/au/org/ala/ecodata/BulkImport.groovy index 28855932c..35228b261 100644 --- a/grails-app/domain/au/org/ala/ecodata/BulkImport.groovy +++ b/grails-app/domain/au/org/ala/ecodata/BulkImport.groovy @@ -24,6 +24,26 @@ class BulkImport { Date dateCreated Date lastUpdated + /** Custom toMap for the bulk import object */ + Map toMap() { + Map bulkImport = [:] + bulkImport.bulkImportId = bulkImportId + bulkImport.dataToLoad = dataToLoad + bulkImport.projectActivityId = projectActivityId + bulkImport.projectId = projectId + bulkImport.formName = formName + bulkImport.description = description + bulkImport.createdActivities = createdActivities + bulkImport.validActivities = validActivities + bulkImport.invalidActivities = invalidActivities + bulkImport.userId = userId + bulkImport.status = status + bulkImport.dateCreated = dateCreated + bulkImport.lastUpdated = lastUpdated + + bulkImport + } + /** The list of properties to be used when binding request data to an ActivityForm */ static bindingProperties = ['dataToLoad', 'projectActivityId', 'projectId', 'formName', 'description', 'createdActivities', 'validActivities', 'invalidActivities', 'userId'] diff --git a/grails-app/services/au/org/ala/ecodata/BulkImportService.groovy b/grails-app/services/au/org/ala/ecodata/BulkImportService.groovy index 877faf149..2b3d8ee16 100644 --- a/grails-app/services/au/org/ala/ecodata/BulkImportService.groovy +++ b/grails-app/services/au/org/ala/ecodata/BulkImportService.groovy @@ -63,7 +63,7 @@ class BulkImportService implements DataBinder { } Map toMap (BulkImport bulkImport, levelOfDetails ) { - def map = commonService.toBareMap(bulkImport) + def map = bulkImport.toMap() if (levelOfDetails == DETAILS_MINIMAL) { map.removeAll {key, value -> key in ['dataToLoad', 'createdActivities', 'validActivities', 'invalidActivities', 'id'] } From 27fbf1ca7797d6567c61563cd7cfb725dd85fcb8 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 11 Apr 2023 10:47:07 +1000 Subject: [PATCH 03/20] Checked in a WIP test to help fix dbo use. #826 --- .../ecodata/TestDboVsDynamicAttributes.groovy | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/test/groovy/au/org/ala/ecodata/TestDboVsDynamicAttributes.groovy diff --git a/src/test/groovy/au/org/ala/ecodata/TestDboVsDynamicAttributes.groovy b/src/test/groovy/au/org/ala/ecodata/TestDboVsDynamicAttributes.groovy new file mode 100644 index 000000000..16294035c --- /dev/null +++ b/src/test/groovy/au/org/ala/ecodata/TestDboVsDynamicAttributes.groovy @@ -0,0 +1,142 @@ +package au.org.ala.ecodata + +import grails.test.mongodb.MongoSpec +import org.grails.datastore.mapping.core.Session +import spock.lang.Ignore + +/** + * This test is not designed to be run as a part of the regular suite - instead it is a one off + * that is attempting to find and document dynamic attributes in the database and allow for a safe + * refactoring to remove use of Entity.getDbo() from the codebase. + */ +@Ignore +class TestDboVsDynamicAttributesSpec extends MongoSpec { + + void "test projects"() { + expect: + true + Project.withSession { Session session -> + + Closure specialConditions = { String key, Map groovy, Map dbo -> + false + } + checkProperties(Project.findAll(), session, specialConditions) + } + } + +// void "test comments"() { +// expect: +// Comment.withSession { Session session -> +// +// Closure specialConditions = { String key, Map groovy, Map dbo -> +// key == 'parentId' || key == 'parent' || key == 'children' +// } +// checkProperties(Comment.findAll(), session, specialConditions) +// } +// } + +// void "test management units"() { +// expect: +// ManagementUnit.withSession { Session session -> +// +// Closure specialConditions = { String key, Map groovy, Map dbo -> +// key == 'reportConfig' || key == 'associatedOrganisations' || key == 'geographicInfo' +// } +// checkProperties(ManagementUnit.findAll(), session, specialConditions) +// } +// } +// void "test programs"() { +// expect: +// Program.withSession { Session session -> +// +// Closure specialConditions = { String key, Map groovy, Map dbo -> +// key == 'inhertitedConfig' || key == 'parentId' || key == 'subPrograms' +// } +// checkProperties(Program.findAll(), session, specialConditions) +// } +// } +// void "test sites"() { +// expect: +// Site.withSession { Session session -> +// +// Closure specialConditions = { String key, Map groovy, Map dbo -> +// key == 'isSciStarter' || key == 'geoPoint' || key == 'compoundSite' || key == 'geometryType' || +// key == 'associations' // getAssociations looks like it doesn't do anything +// } +// checkProperties(Site.findAll(), session, specialConditions) +// } +// } + +// void "test outputs"() { +// expect: +// Output.withSession { Session session -> +// +// Closure specialConditions = { String key, Map groovy, Map dbo -> +// key == "tempArgs" +// } +// checkProperties(Output.findAll(), session, specialConditions) +// } +// } + +// void testActivities() { +// +// expect: +// // Can't use a stateless session as the dbo doesn't work +// Activity.withSession { Session session -> +// Set dynamicAttributes = new HashSet() +// Closure specialConditions = { String key, Map groovy, Map dbo -> +// key == "complete" || key == "assessment" || +// (key == 'progress' && groovy.type == 'OzAtlas Sightings') +// } +// checkProperties(Activity.findAll(), session, specialConditions) +// } +// } + + + + + private Set checkProperties(List entities, Session session, Closure specialConditions) { + int count = 0 + Set dynamicAttributes = new HashSet() + entities.each { + Map dbo = GormMongoUtil.extractPropertiesViaDbo(it) + + Map groovyPlusDynamic = [:] + Map activityProps = it.properties + groovyPlusDynamic.putAll(activityProps) + groovyPlusDynamic.putAll(it.attributes()) + dynamicAttributes.addAll(it.attributes().keySet()) + + dbo.remove('_id') + dbo.remove('version') + groovyPlusDynamic.remove("dbo") + + if (dbo.keySet() != groovyPlusDynamic.keySet()) { + dbo.keySet().minus(groovyPlusDynamic.keySet()).each { + assert dbo[it] == null + } + groovyPlusDynamic.keySet().minus(dbo.keySet()).each { + assert specialConditions(it, groovyPlusDynamic, dbo) || + !groovyPlusDynamic[it] // Accounts for empty collections & null values + } + + } + if (dbo != groovyPlusDynamic) { + dbo.keySet().each { + assert it == "_id" || specialConditions(it, groovyPlusDynamic, dbo) || dbo[it] == groovyPlusDynamic[it] + } + + } + count++ + if (count % 1000 == 0) { + println "Processed $count activities" + session.clear() // SO we don't run out of memory + + } + } + println dynamicAttributes + dynamicAttributes + } + +} + From 343cd41cc3e1fdbafc23e7b261a0087b838a4237 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 11 Apr 2023 10:58:04 +1000 Subject: [PATCH 04/20] Merged dev. #826 --- build.gradle | 5 +---- gradle/jacoco.gradle | 4 ++-- .../ElasticSearchBackwardsCompatibilityMapperSpec.groovy | 9 ++++++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 345a11f46..ed7e81bc3 100644 --- a/build.gradle +++ b/build.gradle @@ -88,8 +88,6 @@ dependencies { implementation "org.grails:grails-plugin-databinding" implementation "org.grails:grails-plugin-codecs" implementation "org.grails.plugins:mongodb:$gormMongoVersion" - // Without this override, 4.6.0 is being included which fails - //implementation "org.mongodb:bson:4.3.0" implementation "org.grails.plugins:gorm-graphql-plugin:2.0.0" // Without this override, 18.1 is being included which is not compatible with the graphql-plugin implementation "com.graphql-java:graphql-java:14.0" @@ -156,8 +154,7 @@ dependencies { testImplementation "org.grails:grails-gorm-testing-support" testImplementation "org.grails.plugins:geb" testImplementation "org.grails:grails-web-testing-support" - testImplementation(platform('org.junit:junit-bom:5.9.1')) - testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' + testImplementation "com.github.tomakehurst:wiremock-jre8-standalone:2.33.2" testImplementation "org.seleniumhq.selenium:selenium-chrome-driver:$seleniumVersion" testRuntimeOnly "org.seleniumhq.selenium:selenium-firefox-driver:$seleniumVersion" diff --git a/gradle/jacoco.gradle b/gradle/jacoco.gradle index 5d674171f..1da464894 100644 --- a/gradle/jacoco.gradle +++ b/gradle/jacoco.gradle @@ -15,7 +15,7 @@ test { finalizedBy jacocoTestReport } jacocoTestReport { - dependsOn test + dependsOn check finalizedBy jacocoTestCoverageVerification afterEvaluate { @@ -39,7 +39,7 @@ jacocoTestCoverageVerification { violationRules { rule { limit { - minimum = 0.16 + minimum = 0.1 } } } diff --git a/src/test/groovy/au/org/ala/ecodata/mapper/ElasticSearchBackwardsCompatibilityMapperSpec.groovy b/src/test/groovy/au/org/ala/ecodata/mapper/ElasticSearchBackwardsCompatibilityMapperSpec.groovy index c4ac6a882..5d1688787 100644 --- a/src/test/groovy/au/org/ala/ecodata/mapper/ElasticSearchBackwardsCompatibilityMapperSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/mapper/ElasticSearchBackwardsCompatibilityMapperSpec.groovy @@ -1,7 +1,9 @@ package au.org.ala.ecodata.mapper +import grails.util.Holders import org.elasticsearch.search.aggregations.Aggregations import org.elasticsearch.search.aggregations.bucket.terms.StringTerms +import org.grails.testing.GrailsUnitTest import spock.lang.Specification /** @@ -9,7 +11,12 @@ import spock.lang.Specification * by this test. * There are functional tests in MERIT that use real data and searches that will catch issues. */ -class ElasticSearchBackwardsCompatibilityMapperSpec extends Specification { +class ElasticSearchBackwardsCompatibilityMapperSpec extends Specification implements GrailsUnitTest { + + void setup() { + Holders.grailsApplication = grailsApplication + } + void "The hit source can be mapped"() { setup: From c690132031c1589a14bf676c8a7b1b6ea104649c Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Apr 2023 08:01:02 +1000 Subject: [PATCH 05/20] 4.2-SNAPSHOT --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 08150ac81..7f1e38eeb 100644 --- a/build.gradle +++ b/build.gradle @@ -22,7 +22,7 @@ plugins { id 'jacoco' } -version "4.1" +version "4.2-SNAPSHOT" group "au.org.ala" description "Ecodata" From af2abc747547c4870b5ae4865f49c6af84b73dc9 Mon Sep 17 00:00:00 2001 From: Chris Date: Mon, 17 Apr 2023 08:05:01 +1000 Subject: [PATCH 06/20] Fixed formatting per review #826 --- grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy b/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy index b10da857c..1f7723c26 100644 --- a/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy +++ b/grails-app/domain/au/org/ala/ecodata/ManagementUnit.groovy @@ -116,7 +116,7 @@ class ManagementUnit { reportConfig += config.projectReports?.collect { [:] + it + [report:"projectReport"] } - } + } return reportConfig } From aacbe1831e6ce4f1982da86f524c13fb874377fd Mon Sep 17 00:00:00 2001 From: Chris Date: Thu, 27 Apr 2023 12:49:31 +1000 Subject: [PATCH 07/20] Added to the ExternalId enum AtlasOfLivingAustralia/fieldcapture#2841 --- grails-app/domain/au/org/ala/ecodata/ExternalId.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grails-app/domain/au/org/ala/ecodata/ExternalId.groovy b/grails-app/domain/au/org/ala/ecodata/ExternalId.groovy index faad72053..07ae6da8c 100644 --- a/grails-app/domain/au/org/ala/ecodata/ExternalId.groovy +++ b/grails-app/domain/au/org/ala/ecodata/ExternalId.groovy @@ -8,7 +8,7 @@ import groovy.transform.EqualsAndHashCode @EqualsAndHashCode class ExternalId implements Comparable { - enum IdType { INTERNAL_ORDER_NUMBER, TECH_ONE_CODE, WORK_ORDER, GRANT_AWARD, GRANT_OPPORTUNITY } + enum IdType { INTERNAL_ORDER_NUMBER, TECH_ONE_CODE, WORK_ORDER, GRANT_AWARD, GRANT_OPPORTUNITY, RELATED_PROJECT } static constraints = { } From 1553a87e475c3d5f256f886b0f1fe8a949a9628f Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 9 May 2023 13:13:53 +1000 Subject: [PATCH 08/20] Added a search for ActivityForms #833 --- .../ala/ecodata/ActivityFormController.groovy | 17 +++++++++++ .../ala/ecodata/ActivityFormService.groovy | 17 +++++++++++ .../ecodata/ActivityFormControllerSpec.groovy | 30 +++++++++++++++++++ .../ecodata/ActivityFormServiceSpec.groovy | 18 +++++++++++ 4 files changed, 82 insertions(+) diff --git a/grails-app/controllers/au/org/ala/ecodata/ActivityFormController.groovy b/grails-app/controllers/au/org/ala/ecodata/ActivityFormController.groovy index 984bb15c6..f057a9997 100644 --- a/grails-app/controllers/au/org/ala/ecodata/ActivityFormController.groovy +++ b/grails-app/controllers/au/org/ala/ecodata/ActivityFormController.groovy @@ -3,6 +3,7 @@ package au.org.ala.ecodata import au.org.ala.web.AlaSecured import grails.converters.JSON import groovy.json.JsonSlurper +import org.apache.http.HttpStatus /** * Responds to requests related to activity forms in ecodata. @@ -29,6 +30,22 @@ class ActivityFormController { respond form } + /** + * Returns ActivityForms that match the supplied search criteria + */ + List search() { + Map searchCriteria = request.JSON + if (!searchCriteria) { + respond ([status:HttpStatus.SC_BAD_REQUEST], [message:"At least one criteria must be supplied"]) + return + } + Map options = null + if (searchCriteria.options) { + options = searchCriteria.remove('options') + } + respond activityFormService.search(searchCriteria, options) + } + /** * Updates the activity form identified by the name and version in the payload. * @return diff --git a/grails-app/services/au/org/ala/ecodata/ActivityFormService.groovy b/grails-app/services/au/org/ala/ecodata/ActivityFormService.groovy index a0f19ea6b..512ddc0be 100644 --- a/grails-app/services/au/org/ala/ecodata/ActivityFormService.groovy +++ b/grails-app/services/au/org/ala/ecodata/ActivityFormService.groovy @@ -1,6 +1,7 @@ package au.org.ala.ecodata import au.org.ala.ecodata.metadata.OutputMetadata +import org.grails.datastore.mapping.query.api.BuildableCriteria /** * Processes requests related to activity forms. @@ -236,4 +237,20 @@ class ActivityFormService { } property } + + List search(Map searchCriteria, Map options = null) { + BuildableCriteria criteria = ActivityForm.createCriteria() + Closure action = { + ne("status", Status.DELETED) + searchCriteria.each { prop, value -> + + if (value instanceof List) { + inList(prop, value) + } else { + eq(prop, value) + } + } + } + options ? criteria.list(options, action) : criteria.list(action) + } } diff --git a/src/test/groovy/au/org/ala/ecodata/ActivityFormControllerSpec.groovy b/src/test/groovy/au/org/ala/ecodata/ActivityFormControllerSpec.groovy index bc0fe2c3e..734d3acdc 100644 --- a/src/test/groovy/au/org/ala/ecodata/ActivityFormControllerSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/ActivityFormControllerSpec.groovy @@ -181,4 +181,34 @@ class ActivityFormControllerSpec extends Specification implements ControllerUnit responseData.status == Status.ACTIVE responseData.type == 'ActivityUpdated' } + + void "The controller delegates a search request to the ActivityFormService"() { + setup: + Map criteria = [type:"Protocol", options:[max:10]] + + when: + request.method = 'POST' + request.json = criteria + controller.search() + + then: + 1 * activityFormService.search([type:"Protocol"], [max:10]) >> [[name:"Test form", formVersion:2]] + response.status == HttpStatus.SC_OK + List responseData = response.json + responseData.size() == 1 + responseData[0].name == "Test form" + responseData[0].formVersion == 2 + } + + void "The search request requires at least one criteria"() { + + when: + request.method = 'POST' + request.json = [:] + controller.search() + + then: + 0 * activityFormService.search(_,_) + response.status == HttpStatus.SC_BAD_REQUEST + } } diff --git a/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy index 49248a117..23b9cc108 100644 --- a/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy @@ -4,6 +4,7 @@ import grails.testing.gorm.DataTest import grails.testing.gorm.DomainUnitTest import grails.testing.services.ServiceUnitTest import groovy.json.JsonSlurper +import spock.lang.Ignore import spock.lang.Specification class ActivityFormServiceSpec extends Specification implements ServiceUnitTest, DataTest { @@ -333,6 +334,23 @@ class ActivityFormServiceSpec extends Specification implements ServiceUnitTest Date: Wed, 10 May 2023 07:45:52 +1000 Subject: [PATCH 09/20] Refactored tests to mongospec #833 --- .../ala/ecodata/ActivityFormServiceSpec.groovy | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy index 23b9cc108..f47689851 100644 --- a/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/ActivityFormServiceSpec.groovy @@ -1,5 +1,6 @@ package au.org.ala.ecodata +import grails.test.mongodb.MongoSpec import grails.testing.gorm.DataTest import grails.testing.gorm.DomainUnitTest import grails.testing.services.ServiceUnitTest @@ -7,15 +8,23 @@ import groovy.json.JsonSlurper import spock.lang.Ignore import spock.lang.Specification -class ActivityFormServiceSpec extends Specification implements ServiceUnitTest, DataTest { +class ActivityFormServiceSpec extends MongoSpec implements ServiceUnitTest { MetadataService metadataService = Mock(MetadataService) void setup() { service.metadataService = metadataService - mockDomain(Score) - mockDomain(ActivityForm) + deleteData() + } + + void cleanup() { + deleteData() + } + private void deleteData() { + ActivityForm.findAll().each { + it.delete(flush:true, failOnError:true) + } } def "Activity forms cannot be saved without the mandatory fields"() { @@ -334,8 +343,6 @@ class ActivityFormServiceSpec extends Specification implements ServiceUnitTest Date: Thu, 11 May 2023 16:23:01 +1000 Subject: [PATCH 10/20] commit updates #836 --- .../org/ala/ecodata/MetadataController.groovy | 4 +++ .../au/org/ala/ecodata/MetadataService.groovy | 28 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/grails-app/controllers/au/org/ala/ecodata/MetadataController.groovy b/grails-app/controllers/au/org/ala/ecodata/MetadataController.groovy index 4d35ed4c8..f563c13bd 100644 --- a/grails-app/controllers/au/org/ala/ecodata/MetadataController.groovy +++ b/grails-app/controllers/au/org/ala/ecodata/MetadataController.groovy @@ -20,6 +20,10 @@ class MetadataController { render metadataService.activitiesList(params.program, params.subprogram) as JSON } + def activitiesListByProgram() { + render metadataService.activitiesListByProgramId(params.programId) as JSON + } + def programsModel() { render metadataService.programsModel() } diff --git a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy index 30d61b166..6eaa4f8c6 100644 --- a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy +++ b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy @@ -135,8 +135,32 @@ class MetadataService { // Remove deprecated activities activities = activities.findAll {!it.status || it.status == ACTIVE} - Map byCategory = [:] + groupActivities(activities) + } + + /** + * Returns a Map of activity types grouped by category. + * @param programId Most of the legacy projects are updated recently to insert programId (see github #2741) + * @return a Map, key: String, value: List of name, description for each activity in the category + */ + Map activitiesListByProgramId(String programId) { + Map config = Program.findByProgramId(programId)?.config + List activities = config.activities.collect{it.name} + List forms = activityFormService.search(category:activities) + List results = forms.collect {[name:it.name, category:it.category, type:it.type, description:it.description, status:it.status]} + results = results.findAll {!it.status || it.status == ACTIVE} + + groupActivities(results) + } + + /** + * Group by the activity category field, falling back on a default grouping of activity or assessment. + * @param activities + * @return a Map + */ + private def groupActivities(List activities) { + Map byCategory = [:] // Group by the activity category field, falling back on a default grouping of activity or assessment. activities.each { def category = it.category?: it.type == 'Activity' ? 'Activities' : 'Assessment' @@ -146,7 +170,7 @@ class MetadataService { def description = messageSource.getMessage("api.${it.name}.description", null, "", Locale.default) byCategory[category] << [name:it.name, type:it.type, description:description] } - byCategory + return byCategory } def programsModel() { From 4e8da0ad4b6cb6482e634b91b40b09488051943e Mon Sep 17 00:00:00 2001 From: salomon-j <90952854+salomon-j@users.noreply.github.com> Date: Mon, 15 May 2023 14:27:44 +1000 Subject: [PATCH 11/20] commit unit tests #836 --- .../ala/ecodata/MetadataServiceSpec.groovy | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy index 3836d6639..a96d89798 100644 --- a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy @@ -5,11 +5,14 @@ import grails.test.mongodb.MongoSpec import grails.testing.services.ServiceUnitTest import org.grails.web.converters.marshaller.json.CollectionMarshaller import org.grails.web.converters.marshaller.json.MapMarshaller +import org.json.simple.JSONArray +import org.json.simple.JSONObject class MetadataServiceSpec extends MongoSpec implements ServiceUnitTest { WebService webService = Mock(WebService) SettingService settingService = Mock(SettingService) + ActivityFormService activityFormService = Mock(ActivityFormService) def setup() { service.grailsApplication = grailsApplication @@ -20,6 +23,7 @@ class MetadataServiceSpec extends MongoSpec implements ServiceUnitTest> activityForms + result != [:] + + } + + def "Program config has no activities"() { + setup: + Program.findAll().each { it.delete() } + String programId = '456' + Program program = new Program(programId:programId, name: 'test 123', description: 'description 1', + config:[excludes:["excludes",["DATA_SETS", "MERI_PLAN"]], projectReports:["reportType":"Activity"]]) + program.save(flush:true, failOnError: true) + + + List activityForms = new ArrayList() + activityForms.add(new ActivityForm(name: 'test', formVersion: 1, supportsSites: true, supportsPhotoPoints: true, type: 'Activity')) + + when: + Map result = service.activitiesListByProgramId(programId) + + then: + 1 * activityFormService.search(_) >> [] + result == [:] + + } + def "excelWorkbookToMap: get content from bulk_import_example.xlsx into a list"() { setup: service.activityFormService = new ActivityFormService() From a0bb57773c7862854b852e67881d64607a1f47bf Mon Sep 17 00:00:00 2001 From: salomon-j <90952854+salomon-j@users.noreply.github.com> Date: Mon, 15 May 2023 14:28:51 +1000 Subject: [PATCH 12/20] removed unused method #836 --- .../groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy index a96d89798..2137263e4 100644 --- a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy @@ -46,13 +46,6 @@ class MetadataServiceSpec extends MongoSpec implements ServiceUnitTest Date: Mon, 15 May 2023 15:03:19 +1000 Subject: [PATCH 13/20] commit publication status filter to avoid duplicate forms being return #836 --- .../au/org/ala/ecodata/MetadataService.groovy | 6 ++++-- .../au/org/ala/ecodata/MetadataServiceSpec.groovy | 11 ++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy index 6eaa4f8c6..38ace0c8a 100644 --- a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy +++ b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy @@ -145,10 +145,12 @@ class MetadataService { */ Map activitiesListByProgramId(String programId) { Map config = Program.findByProgramId(programId)?.config - List activities = config.activities.collect{it.name} + List activities = config?.activities.collect{it.name} - List forms = activityFormService.search(category:activities) + List forms = activityFormService.search(category:activities) + forms = forms.findAll{it.publicationStatus == PublicationStatus.PUBLISHED} List results = forms.collect {[name:it.name, category:it.category, type:it.type, description:it.description, status:it.status]} + results = results.findAll {!it.status || it.status == ACTIVE} groupActivities(results) diff --git a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy index 2137263e4..57d1e2ce0 100644 --- a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy @@ -153,9 +153,18 @@ class MetadataServiceSpec extends MongoSpec implements ServiceUnitTest Date: Mon, 15 May 2023 15:16:47 +1000 Subject: [PATCH 14/20] removed status filter #836 --- grails-app/services/au/org/ala/ecodata/MetadataService.groovy | 3 --- 1 file changed, 3 deletions(-) diff --git a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy index 38ace0c8a..76e5b9390 100644 --- a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy +++ b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy @@ -150,9 +150,6 @@ class MetadataService { List forms = activityFormService.search(category:activities) forms = forms.findAll{it.publicationStatus == PublicationStatus.PUBLISHED} List results = forms.collect {[name:it.name, category:it.category, type:it.type, description:it.description, status:it.status]} - - results = results.findAll {!it.status || it.status == ACTIVE} - groupActivities(results) } From db0c85b137b46acb1cc5dd6f0fedb88d0ab78c24 Mon Sep 17 00:00:00 2001 From: salomon-j <90952854+salomon-j@users.noreply.github.com> Date: Tue, 16 May 2023 15:02:35 +1000 Subject: [PATCH 15/20] commit update #836 --- .../services/au/org/ala/ecodata/MetadataService.groovy | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy index 76e5b9390..a8135ceec 100644 --- a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy +++ b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy @@ -145,10 +145,8 @@ class MetadataService { */ Map activitiesListByProgramId(String programId) { Map config = Program.findByProgramId(programId)?.config - List activities = config?.activities.collect{it.name} - - List forms = activityFormService.search(category:activities) - forms = forms.findAll{it.publicationStatus == PublicationStatus.PUBLISHED} + List activities = config?.activities?.collect{it.name} + List forms = activityFormService.search(publicationStatus:PublicationStatus.PUBLISHED,category:activities) List results = forms.collect {[name:it.name, category:it.category, type:it.type, description:it.description, status:it.status]} groupActivities(results) } From 65ee3db15549c417cb6a4c96602a35563e87a9cf Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 May 2023 09:57:31 +1000 Subject: [PATCH 16/20] Updated gradle build action #838 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 285701289..e7f81cf6e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,17 +42,17 @@ jobs: mongodb-version: '5.0' - name: Build and run jacoco coverage report with Gradle - uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + uses: gradle/gradle-build-action@2.4.2 with: arguments: -PenableJacoco=true jacocoTestCoverageVerification - name: Clean to remove clover instrumentation - uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + uses: gradle/gradle-build-action@2.4.2 with: arguments: clean - name: Publish the JAR to the repository - uses: gradle/gradle-build-action@0d13054264b0bb894ded474f08ebb30921341cee + uses: gradle/gradle-build-action@2.4.2 with: arguments: publish env: From e706cd06751fe2b62a543885420914b5e2c83e21 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 May 2023 10:03:02 +1000 Subject: [PATCH 17/20] Updated gradle build action #838 --- .github/workflows/build.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e7f81cf6e..3849705ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,17 +42,17 @@ jobs: mongodb-version: '5.0' - name: Build and run jacoco coverage report with Gradle - uses: gradle/gradle-build-action@2.4.2 + uses: gradle/gradle-build-action@v2.4.2 with: arguments: -PenableJacoco=true jacocoTestCoverageVerification - name: Clean to remove clover instrumentation - uses: gradle/gradle-build-action@2.4.2 + uses: gradle/gradle-build-action@v2.4.2 with: arguments: clean - name: Publish the JAR to the repository - uses: gradle/gradle-build-action@2.4.2 + uses: gradle/gradle-build-action@v2.4.2 with: arguments: publish env: From 470607be5c9cbdcedb996e6629f33235aeb00006 Mon Sep 17 00:00:00 2001 From: Chris Date: Tue, 23 May 2023 12:47:59 +1000 Subject: [PATCH 18/20] Fixed issues with activitiesListByProgramId #836 --- .../au/org/ala/ecodata/MetadataService.groovy | 11 ++++++-- .../ala/ecodata/MetadataServiceSpec.groovy | 25 ++++++++----------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy index a8135ceec..ff3039cbd 100644 --- a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy +++ b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy @@ -145,8 +145,15 @@ class MetadataService { */ Map activitiesListByProgramId(String programId) { Map config = Program.findByProgramId(programId)?.config - List activities = config?.activities?.collect{it.name} - List forms = activityFormService.search(publicationStatus:PublicationStatus.PUBLISHED,category:activities) + List activityNames = config?.activities?.collect{it.name} + Map criteria = [publicationStatus:PublicationStatus.PUBLISHED] + // If activity names are specified, only return those activities, otherwise return all + if (activityNames) { + criteria.name = activityNames + } + List forms = activityFormService.search(criteria) ?: [] + // The search will return forms with the same name but different version, we need to get the latest formVersion + forms = forms.groupBy{it.name}.collect{it.value.max{it.formVersion}} List results = forms.collect {[name:it.name, category:it.category, type:it.type, description:it.description, status:it.status]} groupActivities(results) } diff --git a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy index 57d1e2ce0..7e2a5eae2 100644 --- a/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/MetadataServiceSpec.groovy @@ -7,12 +7,14 @@ import org.grails.web.converters.marshaller.json.CollectionMarshaller import org.grails.web.converters.marshaller.json.MapMarshaller import org.json.simple.JSONArray import org.json.simple.JSONObject +import org.springframework.context.MessageSource class MetadataServiceSpec extends MongoSpec implements ServiceUnitTest { WebService webService = Mock(WebService) SettingService settingService = Mock(SettingService) ActivityFormService activityFormService = Mock(ActivityFormService) + MessageSource messageSource = Mock(MessageSource) def setup() { service.grailsApplication = grailsApplication @@ -24,6 +26,7 @@ class MetadataServiceSpec extends MongoSpec implements ServiceUnitTest> activityForms - result != [:] + 1 * activityFormService.search([publicationStatus:PublicationStatus.PUBLISHED, name:["test1"]]) >> activityForms + 1 * messageSource.getMessage("api.test1.description", null, "", Locale.default) >> "test1 description" + result == ["C1":[[name:form1.name, type:form1.type, description:"test1 description"]]] } From b65c14b24dc9ebaf7d19681d176d43d60f8f18a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 May 2023 23:32:28 +0000 Subject: [PATCH 19/20] Bump socket.io-parser and socket.io Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) and [socket.io](https://github.com/socketio/socket.io). These dependencies needed to be updated together. Updates `socket.io-parser` from 4.0.5 to 4.2.3 - [Release notes](https://github.com/socketio/socket.io-parser/releases) - [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io-parser/compare/4.0.5...4.2.3) Updates `socket.io` from 4.5.1 to 4.6.1 - [Release notes](https://github.com/socketio/socket.io/releases) - [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io/compare/4.5.1...4.6.1) --- updated-dependencies: - dependency-name: socket.io-parser dependency-type: indirect - dependency-name: socket.io dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 162 +++++++++++++++++++++++----------------------- 1 file changed, 80 insertions(+), 82 deletions(-) diff --git a/package-lock.json b/package-lock.json index 168f272b9..88f16e300 100644 --- a/package-lock.json +++ b/package-lock.json @@ -524,6 +524,12 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, "node_modules/@sphinxxxx/color-conversion": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", @@ -535,12 +541,6 @@ "integrity": "sha512-1c4ZOETSRpI0iBfIFUqU4KqwBAB2lHUAlBjZz/YqOHqwM9dTTzjV6Km0ZkiEiSCx/tLr1BtESIKyWWMww+RUqw==", "dev": true }, - "node_modules/@types/component-emitter": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", - "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", - "dev": true - }, "node_modules/@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -548,10 +548,13 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/eslint": { "version": "8.4.3", @@ -1294,12 +1297,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1589,9 +1586,9 @@ } }, "node_modules/engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -1603,16 +1600,16 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "engines": { "node": ">=10.0.0" } }, "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", "dev": true, "engines": { "node": ">=10.0.0" @@ -3810,36 +3807,38 @@ } }, "node_modules/socket.io": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz", - "integrity": "sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.0.4" + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "dependencies": { + "ws": "~8.11.0" + } }, "node_modules/socket.io-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", - "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz", + "integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==", "dev": true, "dependencies": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" }, "engines": { @@ -4451,9 +4450,9 @@ "dev": true }, "node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4890,6 +4889,12 @@ "integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==", "peer": true }, + "@socket.io/component-emitter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", + "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==", + "dev": true + }, "@sphinxxxx/color-conversion": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz", @@ -4901,12 +4906,6 @@ "integrity": "sha512-1c4ZOETSRpI0iBfIFUqU4KqwBAB2lHUAlBjZz/YqOHqwM9dTTzjV6Km0ZkiEiSCx/tLr1BtESIKyWWMww+RUqw==", "dev": true }, - "@types/component-emitter": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", - "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==", - "dev": true - }, "@types/cookie": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", @@ -4914,10 +4913,13 @@ "dev": true }, "@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "requires": { + "@types/node": "*" + } }, "@types/eslint": { "version": "8.4.3", @@ -5520,12 +5522,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5752,9 +5748,9 @@ } }, "engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -5766,13 +5762,13 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" } }, "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.6.tgz", + "integrity": "sha512-tjuoZDMAdEhVnSFleYPCtdL2GXwVTGtNjoeJd9IhIG3C1xs9uwxqRNEu5WpnDZCaozwVlK/nuQhpodhXSIMaxw==", "dev": true }, "enhanced-resolve": { @@ -7388,33 +7384,35 @@ "dev": true }, "socket.io": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.1.tgz", - "integrity": "sha512-0y9pnIso5a9i+lJmsCdtmTTgJFFSvNQKDnPQRz28mGNnxbmqYg2QPtJTLFxhymFZhAIn50eHAKzJeiNaKr+yUQ==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.0.4" + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" } }, "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "requires": { + "ws": "~8.11.0" + } }, "socket.io-parser": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.5.tgz", - "integrity": "sha512-sNjbT9dX63nqUFIOv95tTVm6elyIU4RvB1m8dOeZt+IgWwcWklFDOdmGcfo3zSiRsnR/3pJkjY5lfoGqEe4Eig==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz", + "integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==", "dev": true, "requires": { - "@types/component-emitter": "^1.2.10", - "component-emitter": "~1.3.0", + "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1" } }, @@ -7823,9 +7821,9 @@ "dev": true }, "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "requires": {} }, From 3c4d0f278c1a0b5977c15f11b0a94548b0978cfc Mon Sep 17 00:00:00 2001 From: Chris Date: Fri, 26 May 2023 10:06:16 +1000 Subject: [PATCH 20/20] Use inherited config, spelling fix #836 --- grails-app/domain/au/org/ala/ecodata/Program.groovy | 4 ++-- .../services/au/org/ala/ecodata/ElasticSearchService.groovy | 4 ++-- grails-app/services/au/org/ala/ecodata/MetadataService.groovy | 2 +- src/test/groovy/au/org/ala/ecodata/ProgramSpec.groovy | 3 +-- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/grails-app/domain/au/org/ala/ecodata/Program.groovy b/grails-app/domain/au/org/ala/ecodata/Program.groovy index 11fcba9d4..8ce085f8c 100644 --- a/grails-app/domain/au/org/ala/ecodata/Program.groovy +++ b/grails-app/domain/au/org/ala/ecodata/Program.groovy @@ -69,7 +69,7 @@ class Program { program.assets = assets program.outcomes = outcomes program.priorities = priorities - program.inheritedConfig = getInhertitedConfig() + program.inheritedConfig = getInheritedConfig() program.config = config program.risks = risks program.parent = populateParentProgramSummary(parent) @@ -104,7 +104,7 @@ class Program { } - Map getInhertitedConfig() { + Map getInheritedConfig() { Program program = this Deque allConfig = new LinkedList() while(program != null) { diff --git a/grails-app/services/au/org/ala/ecodata/ElasticSearchService.groovy b/grails-app/services/au/org/ala/ecodata/ElasticSearchService.groovy index 8481df07b..4a9f68bf0 100644 --- a/grails-app/services/au/org/ala/ecodata/ElasticSearchService.groovy +++ b/grails-app/services/au/org/ala/ecodata/ElasticSearchService.groovy @@ -1035,8 +1035,8 @@ class ElasticSearchService { } // This allows all projects associated with a particular program to be excluded from indexing. // This is required to allow MERIT projects to be loaded before they have been announced. - if (program.inhertitedConfig?.visibility) { - projectMap.visibility = program.inhertitedConfig.visibility + if (program.inheritedConfig?.visibility) { + projectMap.visibility = program.inheritedConfig.visibility } } else { diff --git a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy index ff3039cbd..a2032fe34 100644 --- a/grails-app/services/au/org/ala/ecodata/MetadataService.groovy +++ b/grails-app/services/au/org/ala/ecodata/MetadataService.groovy @@ -144,7 +144,7 @@ class MetadataService { * @return a Map, key: String, value: List of name, description for each activity in the category */ Map activitiesListByProgramId(String programId) { - Map config = Program.findByProgramId(programId)?.config + Map config = Program.findByProgramId(programId)?.inheritedConfig List activityNames = config?.activities?.collect{it.name} Map criteria = [publicationStatus:PublicationStatus.PUBLISHED] // If activity names are specified, only return those activities, otherwise return all diff --git a/src/test/groovy/au/org/ala/ecodata/ProgramSpec.groovy b/src/test/groovy/au/org/ala/ecodata/ProgramSpec.groovy index 404942a1b..07480e2cd 100644 --- a/src/test/groovy/au/org/ala/ecodata/ProgramSpec.groovy +++ b/src/test/groovy/au/org/ala/ecodata/ProgramSpec.groovy @@ -2,7 +2,6 @@ package au.org.ala.ecodata import com.mongodb.BasicDBObject import grails.test.mongodb.MongoSpec -import spock.lang.Specification /** * Tests the mappings in the Program class. @@ -49,7 +48,7 @@ class ProgramSpec extends MongoSpec { p3.save(flush:true, failOnError: true) when: - Map config = p3.getInhertitedConfig() + Map config = p3.getInheritedConfig() then: