diff --git a/gradle.properties b/gradle.properties
index 5699c1c4..0cdd70e2 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,4 +1,4 @@
-profileHubVersion=4.0-MANGROVE-SNAPSHOT
+profileHubVersion=4.1-SNAPSHOT
grailsVersion=5.2.4
grailsGradlePluginVersion=5.2.3
groovyVersion=3.0.11
diff --git a/grails-app/assets/javascripts/profileEditor/controllers/DoiController.js b/grails-app/assets/javascripts/profileEditor/controllers/DoiController.js
index 5b3252fd..60eadcb3 100644
--- a/grails-app/assets/javascripts/profileEditor/controllers/DoiController.js
+++ b/grails-app/assets/javascripts/profileEditor/controllers/DoiController.js
@@ -37,4 +37,10 @@ profileEditor.controller('DoiController', function (util, $filter, profileServic
}
});
}
+
+ self.trackDownload = function (context, opusId, profileId, publicationId) {
+ var url = context + '/opus/' + opusId + '/profile/' + profileId + '/publication/' + publicationId + '/file'
+ profileService.trackPageview(url);
+ }
+
});
\ No newline at end of file
diff --git a/grails-app/assets/javascripts/profileEditor/controllers/ExportController.js b/grails-app/assets/javascripts/profileEditor/controllers/ExportController.js
index 442c6f32..e0a5bcbd 100644
--- a/grails-app/assets/javascripts/profileEditor/controllers/ExportController.js
+++ b/grails-app/assets/javascripts/profileEditor/controllers/ExportController.js
@@ -1,7 +1,7 @@
/**
* Export controller
*/
-profileEditor.controller('ExportController', function (util, $window, $modal, $http, config) {
+profileEditor.controller('ExportController', function (util, $window, $modal, $http, config, profileService) {
var self = this;
self.profileId = util.getEntityId("profile");
@@ -49,6 +49,8 @@ profileEditor.controller('ExportController', function (util, $window, $modal, $h
} else {
$http.get(url);
}
+
+ profileService.trackPageview(url);
});
}
});
diff --git a/grails-app/assets/javascripts/profileEditor/directives/publication.js b/grails-app/assets/javascripts/profileEditor/directives/publication.js
index 505c1abb..40aae4f5 100644
--- a/grails-app/assets/javascripts/profileEditor/directives/publication.js
+++ b/grails-app/assets/javascripts/profileEditor/directives/publication.js
@@ -12,8 +12,12 @@ profileEditor.directive('publication', function ($browser) {
prefix: '@'
},
templateUrl: '/profileEditor/publication.htm',
- controller: ['$scope', 'config', function ($scope, config) {
+ controller: ['$scope', 'config', 'profileService', function ($scope, config, profileService) {
$scope.context = config.contextPath;
+ $scope.trackDownload = function (context, opusId, profileId, publicationId) {
+ var url = context + '/opus/' + opusId + '/profile/' + profileId + '/publication/' + publicationId + '/file'
+ profileService.trackPageview(url);
+ }
}],
link: function (scope, element, attrs, ctrl) {
diff --git a/grails-app/assets/javascripts/profileEditor/services/ProfileService.js b/grails-app/assets/javascripts/profileEditor/services/ProfileService.js
index 5644bbb1..a90a57ac 100644
--- a/grails-app/assets/javascripts/profileEditor/services/ProfileService.js
+++ b/grails-app/assets/javascripts/profileEditor/services/ProfileService.js
@@ -1277,6 +1277,22 @@ profileEditor.service('profileService', function ($http, util, $cacheFactory, co
loadMasterListItems: function(opus) {
var future = $http.get(util.contextRoot() + '/opus/' + opus.uuid + '/masterList/keybaseItems', {disableAlertOnFailure: true });
return util.toStandardPromise(future);
+ },
+
+ trackPageview: function (url, referrer) {
+ if ((typeof fathom !== 'undefined') && fathom.trackPageview) {
+ var payload = { };
+ if (url) {
+ payload.url = url;
+ }
+
+ if (referrer) {
+ payload.referrer = referrer;
+ }
+
+ console.debug("Tracking pageview with payload: " + JSON.stringify(payload));
+ fathom.trackPageview(payload);
+ }
}
}
});
diff --git a/grails-app/assets/javascripts/profileEditor/templates/publication.tpl.htm b/grails-app/assets/javascripts/profileEditor/templates/publication.tpl.htm
index 0609c189..13a5eab1 100644
--- a/grails-app/assets/javascripts/profileEditor/templates/publication.tpl.htm
+++ b/grails-app/assets/javascripts/profileEditor/templates/publication.tpl.htm
@@ -17,7 +17,7 @@
Download PDF
View Profile
diff --git a/package-lock.json b/package-lock.json
index 1b5ddec1..5ff9acf9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5459,10 +5459,9 @@
}
},
"body-parser": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
- "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==",
-
+ "version": "1.20.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
+ "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==",
"dev": true,
"requires": {
"bytes": "3.1.2",
@@ -5473,91 +5472,10 @@
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
- "qs": "6.11.0",
+ "qs": "6.10.3",
"raw-body": "2.5.1",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
- },
- "dependencies": {
- "bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "dev": true
- },
- "depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "dev": true
- },
- "http-errors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
- "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
- "dev": true,
- "requires": {
- "depd": "2.0.0",
- "inherits": "2.0.4",
- "setprototypeof": "1.2.0",
- "statuses": "2.0.1",
- "toidentifier": "1.0.1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "dev": true,
- "requires": {
- "ee-first": "1.1.1"
- }
- },
- "qs": {
- "version": "6.11.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
- "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
- "dev": true,
- "requires": {
- "side-channel": "^1.0.4"
- }
- },
- "raw-body": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
- "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
- "dev": true,
- "requires": {
- "bytes": "3.1.2",
- "http-errors": "2.0.0",
- "iconv-lite": "0.4.24",
- "unpipe": "1.0.0"
- }
- },
- "setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "dev": true
- },
- "statuses": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
- "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
- "dev": true
- },
- "toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "dev": true
- }
}
},
"boom": {
@@ -6018,15 +5936,11 @@
"integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==",
"dev": true
},
- "call-bind": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
- "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
- "dev": true,
- "requires": {
- "function-bind": "^1.1.1",
- "get-intrinsic": "^1.0.2"
- }
+ "bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true
},
"call-bind": {
"version": "1.0.2",
@@ -6074,40 +5988,9 @@
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
- "ansi-styles": "^1.1.0",
- "escape-string-regexp": "^1.0.0",
- "has-ansi": "^0.1.0",
- "strip-ansi": "^0.3.0",
- "supports-color": "^0.2.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
- "integrity": "sha512-sGwIGMjhYdW26/IhwK2gkWWI8DRCVO6uj3hYgHT+zD+QL1pa37tM3ujhyfcJIYSbsxp7Gxhy7zrRW/1AHm4BmA==",
- "dev": true
- },
- "ansi-styles": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
- "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
- "dev": true
- },
- "strip-ansi": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
- "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
- "dev": true,
- "requires": {
- "ansi-regex": "^0.2.1"
- }
- },
- "supports-color": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
- "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
- "dev": true
- }
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
}
},
"chmodr": {
@@ -6381,6 +6264,12 @@
"integrity": "sha512-v+7uBd1pqe5YtgPacIIbZ8HuHeLFVNe4mUEyFDXL6KiqzEykjbw+5mXZXpGFgNVasdL4jWKgaKIXrEHiynN1LA==",
"dev": true
},
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "dev": true
+ },
"destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
@@ -6840,9 +6729,9 @@
"dev": true
},
"get-intrinsic": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
- "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
"dev": true,
"requires": {
"function-bind": "^1.1.1",
@@ -6961,12 +6850,6 @@
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"dev": true
},
- "has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
- "dev": true
- },
"hawk": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz",
@@ -6991,6 +6874,27 @@
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
"dev": true
},
+ "http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dev": true,
+ "requires": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "dependencies": {
+ "statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "dev": true
+ }
+ }
+ },
"http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
@@ -7090,6 +6994,21 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz",
"integrity": "sha512-Kak1hi6/hYHGVPmdyiZijoQyz5x2iGVzs6w9GYB/HiXEtylY7tIoYEROMjvM1d9nXJqPOrG2MNPMn01bJ+S0Rw==",
"dev": true
+ },
+ "strip-ansi": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+ "integrity": "sha512-DerhZL7j6i6/nEnVG0qViKXI0OKouvvpsAiaj7c+LfqZZZxdwZtv8+UiA/w4VUJpT8UzX0pR1dcHOii1GbmruQ==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^0.2.1"
+ }
+ },
+ "supports-color": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+ "integrity": "sha512-tdCZ28MnM7k7cJDJc7Eq80A9CsRFAAOZUy41npOZCs++qSjfIy7o5Rh46CBk+Dk5FbKJ33X3Tqg4YrV07N5RaA==",
+ "dev": true
}
}
},
@@ -7386,9 +7305,9 @@
"dev": true
},
"json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
+ "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
"dev": true
},
"jsonfile": {
@@ -7851,12 +7770,6 @@
"integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
"dev": true
},
- "object-inspect": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
- "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
- "dev": true
- },
"on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
@@ -8026,12 +7939,33 @@
"integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==",
"dev": true
},
+ "qs": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz",
+ "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==",
+ "dev": true,
+ "requires": {
+ "side-channel": "^1.0.4"
+ }
+ },
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"dev": true
},
+ "raw-body": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz",
+ "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==",
+ "dev": true,
+ "requires": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
"read": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
@@ -8244,6 +8178,12 @@
}
}
},
+ "setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "dev": true
+ },
"shell-quote": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.4.3.tgz",
@@ -8541,6 +8481,12 @@
"is-number": "^7.0.0"
}
},
+ "toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "dev": true
+ },
"touch": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/touch/-/touch-0.0.2.tgz",
@@ -8599,9 +8545,9 @@
}
},
"ua-parser-js": {
- "version": "0.7.33",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
- "integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==",
+ "version": "0.7.31",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
+ "integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==",
"dev": true
},
"uglify-js": {
diff --git a/src/main/groovy/au/org/ala/profile/analytics/Analytics.java b/src/main/groovy/au/org/ala/profile/analytics/Analytics.java
deleted file mode 100644
index 96d4aaae..00000000
--- a/src/main/groovy/au/org/ala/profile/analytics/Analytics.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package au.org.ala.profile.analytics;
-
-import java.lang.annotation.*;
-
-/**
- * Indicates that a controller action (or entire controller) requires
- * reporting pageviews to the analytics service from the server side.
- */
-@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface Analytics {
-}
diff --git a/src/main/groovy/au/org/ala/profile/analytics/GoogleAnalyticsClient.java b/src/main/groovy/au/org/ala/profile/analytics/GoogleAnalyticsClient.java
deleted file mode 100644
index b7e6d255..00000000
--- a/src/main/groovy/au/org/ala/profile/analytics/GoogleAnalyticsClient.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package au.org.ala.profile.analytics;
-
-import retrofit2.Call;
-import retrofit2.http.Field;
-import retrofit2.http.FieldMap;
-import retrofit2.http.FormUrlEncoded;
-import retrofit2.http.POST;
-
-import java.util.Map;
-
-public interface GoogleAnalyticsClient {
-
- @FormUrlEncoded
- @POST("collect")
- Call
collect(
- @Field("v") String version,
- @Field("tid") String trackingId,
- @Field("cid") String clientId,
- @Field("t") String hitType,
- @FieldMap Map otherParams
- );
-
-}
diff --git a/src/main/groovy/au/org/ala/profile/analytics/GoogleAnalyticsClientFactory.java b/src/main/groovy/au/org/ala/profile/analytics/GoogleAnalyticsClientFactory.java
deleted file mode 100644
index d6c653e2..00000000
--- a/src/main/groovy/au/org/ala/profile/analytics/GoogleAnalyticsClientFactory.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package au.org.ala.profile.analytics;
-
-import retrofit2.Retrofit;
-
-/**
- * Factory bean for generating a GoogleAnalyticsClient instance for Spring
- */
-public class GoogleAnalyticsClientFactory {
-
- private String baseUrl;
-
- public GoogleAnalyticsClientFactory() {}
-
- public GoogleAnalyticsClient getInstance() {
- Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).build();
- return retrofit.create(GoogleAnalyticsClient.class);
- }
-
- public void setBaseUrl(String baseUrl) {
- this.baseUrl = baseUrl;
- }
-}
diff --git a/src/main/groovy/au/org/ala/profile/api/OpusResponse.groovy b/src/main/groovy/au/org/ala/profile/api/OpusResponse.groovy
new file mode 100644
index 00000000..b1c5a1e4
--- /dev/null
+++ b/src/main/groovy/au/org/ala/profile/api/OpusResponse.groovy
@@ -0,0 +1,62 @@
+package au.org.ala.profile.api
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties
+import groovy.transform.Canonical
+
+@Canonical
+@JsonIgnoreProperties('metaClass')
+class OpusResponse {
+ String uuid
+ String dataResourceUid
+ String title
+ String shortName
+ String description
+ String masterListUid
+ Map dataResourceConfig
+ String approvedImageOption
+ List approvedLists
+ List featureLists
+ String featureListSectionName
+ Map brandingConfig
+ Map profileLayoutConfig
+ Map opusLayoutConfig
+ Map theme
+ Map help
+ String keybaseProjectId
+ String keybaseKeyId
+ String attributeVocabUuid
+ String authorshipVocabUuid
+ String groupVocabUuid
+ boolean autoDraftProfiles
+ String glossaryUuid
+ List attachments
+ boolean enablePhyloUpload
+ boolean enableOccurrenceUpload
+ boolean enableTaxaUpload
+ boolean enableKeyUpload
+ boolean privateCollection
+ boolean keepImagesPrivate
+ boolean usePrivateRecordData
+ Map mapConfig
+ List supportingOpuses
+ List requestedSupportingOpuses
+ List sharingDataWith
+ boolean autoApproveShareRequests
+ boolean allowCopyFromLinkedOpus
+ boolean showLinkedOpusAttributes
+ boolean allowFineGrainedAttribution
+ List authorities
+ String copyrightText
+ String footerText
+ Map contact
+ boolean hasAboutPage
+ int profileCount
+ String florulaListId
+ String aboutHtml
+ String citationHtml
+ String citationProfile
+ List tags
+ List additionalStatuses
+ Long dateCreated
+ Long lastUpdated
+}
diff --git a/src/test/groovy/au/org/ala/profile/api/ApiControllerSpec.groovy b/src/test/groovy/au/org/ala/profile/api/ApiControllerSpec.groovy
index 5d01467c..ee560ec6 100644
--- a/src/test/groovy/au/org/ala/profile/api/ApiControllerSpec.groovy
+++ b/src/test/groovy/au/org/ala/profile/api/ApiControllerSpec.groovy
@@ -17,6 +17,36 @@ class ApiControllerSpec extends Specification implements ControllerUnitTest> [uuid: 'abc']
+
+ when:
+ params.opusId = opusId
+ controller.getOpus()
+
+ then:
+ response.status == responseCode
+
+ where:
+ opusId | responseCode
+ null | 400
+ 'abc' | 404
+ 'opus1' | 200
+ }
+
+ void "getOpus output should not contain access token"() {
+ setup:
+ profileService.getOpus('opus1') >> [uuid: 'abc', accessToken: 'test1']
+
+ when:
+ params.opusId = "opus1"
+ controller.getOpus()
+
+ then:
+ response.json.accessToken == null
+ }
+
void "getProfiles should be provided with opus id parameter"() {
setup:
profileService.getOpus('opus1') >> [uuid: 'abc']
diff --git a/src/test/groovy/au/org/ala/profile/hub/AnalyticsInterceptorSpec.groovy b/src/test/groovy/au/org/ala/profile/hub/AnalyticsInterceptorSpec.groovy
deleted file mode 100644
index 56289015..00000000
--- a/src/test/groovy/au/org/ala/profile/hub/AnalyticsInterceptorSpec.groovy
+++ /dev/null
@@ -1,156 +0,0 @@
-package au.org.ala.profile.hub
-
-import au.org.ala.plugins.openapi.Path
-import au.org.ala.profile.analytics.Analytics
-import au.org.ala.profile.api.ProfileBriefResponse
-import au.org.ala.web.AuthService
-import au.org.ala.web.UserDetails
-import grails.converters.JSON
-import grails.events.Events
-import grails.testing.web.interceptor.InterceptorUnitTest
-import groovy.util.logging.Slf4j
-import org.grails.web.servlet.mvc.GrailsWebRequest
-import org.grails.web.util.GrailsApplicationAttributes
-import spock.lang.Specification
-
-import javax.servlet.http.Cookie
-import java.security.Principal
-
-/*
- * Copyright (C) 2021 Atlas of Living Australia
- * All Rights Reserved.
- *
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * Created by Temi on 23/8/21.
- */
-@Slf4j
-class AnalyticsInterceptorSpec extends Specification implements InterceptorUnitTest {
-
- def controller
-
- def setup() {
- defineBeans {
- authService(MockAuthService)
- webServiceWrapperService(WebServiceWrapperService)
- }
-
- grailsApplication.addArtefact("Controller", ExampleController)
- grailsApplication.config.security.authorisation.disable = false
- grailsApplication.config.lists.base.url = "http://lists.ala.org.au"
- grailsApplication.config.image.staging.dir = "/data/profile-hub/"
- grailsApplication.config.app.analytics = [apiid: "cd1", collectionid: "cd3", profileid: "cd4", userid: "cd2"]
- }
-
- void "Send appropriate data to GA depending on called controller action"() {
- setup:
-
- interceptor.analyticsService = Mock(AnalyticsService)
- controller = (ExampleController) mockController(ExampleController)
- interceptor.match(controller: "example")
-
- when:
- params.opusId = "public1"
- request.method = "GET"
- request.addHeader(MockAuthService.DEFAULT_AUTH_HEADER, userId)
- request.cookies = [new Cookie('_ga', 'GA1.1.abc.123')].toArray()
- request.requestURI = "/opus/public1/profile"
- request.setAttribute(GrailsApplicationAttributes.CONTROLLER_NAME_ATTRIBUTE, 'example')
- request.setAttribute(GrailsApplicationAttributes.ACTION_NAME_ATTRIBUTE, 'publicAction')
- withInterceptors(controller: "example", action: "publicAction") {
- controller.publicAction()
- }
-
- then:
- response.status == responseCode
- 1 * interceptor.analyticsService.pageView("localhost", "/opus/public1/profile", 'abc.123', "127.0.0.1", null, null, payload)
-
- where:
- userId | responseCode | payload
- "" | 200 | [dt: "List profiles in a collection", cd1: "/opus/{opusId}/profile", cd3: "public1"]
- "123" | 200 | [dt: "List profiles in a collection", cd1: "/opus/{opusId}/profile", cd3: "public1", cd2: "123"]
-
- }
-}
-
-
-class User implements Principal {
-
- Map attributes
-
- User(Map attributes) {
- this.attributes = attributes
- }
-
- @Override
- String getName() {
- return "Fred"
- }
-
- Map getAttributes() {
- return attributes
- }
-}
-
-@Analytics
-class ExampleController {
- MockAnalyticsService analyticsService
- @Path("/opus/{opusId}/profile")
- @io.swagger.v3.oas.annotations.Operation(
- summary = "List profiles in a collection",
- operationId = "/opus/{opusId}/profile",
- method = "GET",
- responses = [
- @io.swagger.v3.oas.annotations.responses.ApiResponse(
- responseCode = "200",
- content = @io.swagger.v3.oas.annotations.media.Content(
- mediaType = "application/json",
- array = @io.swagger.v3.oas.annotations.media.ArraySchema(
- schema = @io.swagger.v3.oas.annotations.media.Schema(
- implementation = ProfileBriefResponse.class
- )
- )
- ),
- headers = [
- @io.swagger.v3.oas.annotations.headers.Header(name = 'X-Total-Count', description = "Total number of profiles", schema = @io.swagger.v3.oas.annotations.media.Schema(type = "integer")),
- @io.swagger.v3.oas.annotations.headers.Header(name = 'Access-Control-Allow-Headers', description = "CORS header", schema = @io.swagger.v3.oas.annotations.media.Schema(type = "String")),
- @io.swagger.v3.oas.annotations.headers.Header(name = 'Access-Control-Allow-Methods', description = "CORS header", schema = @io.swagger.v3.oas.annotations.media.Schema(type = "String")),
- @io.swagger.v3.oas.annotations.headers.Header(name = 'Access-Control-Allow-Origin', description = "CORS header", schema = @io.swagger.v3.oas.annotations.media.Schema(type = "String"))
- ]
- )
- ]
- )
- def publicAction() {
- [:] as JSON
- }
-}
-
-class MockAuthService extends AuthService implements Events {
- static final String DEFAULT_AUTH_HEADER = "X-ALA-userId"
- @Override
- UserDetails getUserForEmailAddress(String emailAddress) {
- if (emailAddress) {
- new UserDetails(userId: "123")
- }
- }
-
- @Override
- String getUserId(){
- def userId = GrailsWebRequest.lookup()?.getHeader(DEFAULT_AUTH_HEADER)
- userId
- }
-}
-
-class MockAnalyticsService extends AnalyticsService implements Events {
- @Override
- void pageView(String hostname, String path, String clientId, String userIp, String userAgent, String referrer, Map payload = [:]) {
- }
-}
\ No newline at end of file
diff --git a/src/test/js/specs/services/ProfileServiceSpec.js b/src/test/js/specs/services/ProfileServiceSpec.js
index 7cd2a2c8..5eab2231 100644
--- a/src/test/js/specs/services/ProfileServiceSpec.js
+++ b/src/test/js/specs/services/ProfileServiceSpec.js
@@ -438,4 +438,23 @@ describe("ProfileService tests", function () {
http.expectGET("/someContext/ws/image/abcdefghijlkmnop").respond("bla");
});
+
+ it("should invoke GET request when trackService is called", function() {
+ window.fathom = {
+ trackPageview: function(payload) {
+
+ http.get(payload.url);
+ }
+ };
+
+ spyOn(window.fathom, 'trackPageview');
+ service.trackPageview('/opus/xyz/profile/abc/pdf');
+
+ expect(window.fathom.trackPageview).toHaveBeenCalledWith({url: '/opus/xyz/profile/abc/pdf'});
+
+ // Ignore below lines. added to prevent call to http.flush from throwing an error
+ service.getImageMetadata('abcdefghijlkmnop', true);
+ http.expectGET("/someContext/ws/image/abcdefghijlkmnop").respond("bla");
+ // end ignore
+ });
});
\ No newline at end of file