diff --git a/.babelrc b/.babelrc
index 0073bc468..607d0d1ba 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,8 +1,15 @@
{
"presets": [
- "env"
+ "@babel/preset-env"
],
+ env: {
+ test: {
+ plugins: [
+ '@babel/plugin-proposal-class-properties',
+ ]
+ }
+ },
"plugins": [
- "transform-regenerator"
+ "transform-regenerator",
]
}
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..17cbd4a67
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,52 @@
+## Description
+
+A meaningful description of proposed change in your own words.
+
+## Related Issue
+
+
+## How to test it locally
+
+
+## Screenshots
+
+
+## Changelog
+
+### Added
+
+### Updated
+
+### Removed
+
+
+## Checklist
+
+- [ ] 🚀 is the code ready to be merged and go live?
+- [ ] 🛠 does it work (build) locally
+
+### Pull Request
+
+- [ ] 📰 good title
+- [ ] 📝good description
+- [ ] 🔖 issue linked
+- [ ] 📖 changelog filled out
+
+### Commits
+
+- [ ] commits are clean
+- [ ] commit messages are clean
+
+### Code Quality
+
+- [ ] 🚧 no commented out code
+- [ ] 🖨 no unnecessary logging
+- [ ] 🎱 no magic numbers
+- [ ] ⚙️ ran jslint
+- [ ] 🧰 ran codeclimate locally
+
+### Testing
+
+- [ ] ✅ added (appropriate) unit tests
+- [ ] 💢 edge cases in tests were considered
+- [ ] ✅ ran tests locally & are passing
diff --git a/.travis.yml b/.travis.yml
index f13a8a34d..f9d48662f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,21 +1,12 @@
os: linux
-language: python
-python:
- - "3.7"
-addons:
- chrome: stable
+language: node_js
+node_js:
+ - "14"
cache:
- - pip
- yarn: true
- directories:
- node_modules
install:
- - pip install -r requirements.txt
-services:
- - docker
-before_script:
- - docker-compose up -d
+ - npm install
script:
- - ./run_test.sh
-after_script:
- - docker-compose down
+ - npm test
diff --git a/README.md b/README.md
index 00c20e047..945da85a6 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,43 @@
-# Installation
+# Introduction
+Wazimap-NG is the next version of [Wazimap](http://www.wazimap.co.za). It provides a platform for users to bind tabular data to spatial boundaries in order create curated views of datasets. Yes - that's probably too vague a description to understand what it is. Hopefully the images below provide a better description:
+
+
+
+
+See a link to the beta site here: [https://beta.youthexplorer.org.za](https://beta.youthexplorer.org.za).
+
+You can find the frontend code in this repository. The backend is available here: [https://github.com/openupsa/wazimap-ng](https://github.com/openupsa/wazimap-ng).
+
+# New features
+
+The main new features are:
+
+* Admins now have more flexibility when it comes to loading data. This includes uploading massive datasets and then slicing and dicing in the backend rather than pre-preparing datasets beforehand.
+* Point data is now fully integrated as a first-class spatial object.
+* Choropleths built into the main view. These were hidden behind multiple clicks in the previous version.
+* One platform can host multiple profiles off the same database.
+* The Rich data view allows richer disaggregation of indicators.
+* The administrator can configure the view to use custom basemaps, colours, and other UI settings.
+* Arbitrary spatial boundaries and hierarchies can be loaded onto the same server.
+* Toggling of overlapping boundary layers such as switching between wards and mainplaces which typically cover the same areas.
+* Integration into third-party data sources for realtime data feeds.
+
+# Related software
+There is no shortage of mapping software available, both commerical and open-source. Wazimap focuses on providing a platform for data custodians to showcase their datasets and mashing them up with public data. The most similar tool that we have found is the excellent [GeoNode](https://geonode.org/). We feel that approach to publishing data is significantly different enough to warrant a separate project.
+
+# Roadmap
+Version 0.8 is due soon and will fix bugs that currently don't have workarounds. We'll publish the 1.0 roadmap soon.
+# Future features
+* WFS endpoint for publishing data to other GIS software
+* Pluggable data visualisations
+* Better handling of geography hierarchies.
+* Improved handling of temporal and other types of non-census-like data.
+* Speed improvements
+* A large standard database of public datasets.
+
+
+# Installation
```bash
@@ -14,3 +52,16 @@ yarn push-gh-pages # pushes to github for hosting
```
+# Documentation
+These are works in progress:
+
+* [Technical manual](https://openup.gitbook.io/wazi-ng-technical/)
+* [Administrator manual](https://openup.gitbook.io/wazimap-ng/)
+
+# Contributions
+Contributions are welcome - we are working towards making this process easier.
+
+# Shoulders of giants
+This project is the next iteration of a number of excellent projects starting with [CensusReporter](https://censusreporter.org/) and [Wazimap](http://www.wazimap.co.za) that followed it. Special thanks to William Bird from [Media Monitoring Africa](https://mediamonitoringafrica.org) whose initial idea (and funding) it was to build a tool to help journalists better understand areas they were reporting on. Also thanks to Chris Berens from [VPUU](vpuu.org.za) who directed funding to help kickstart this new build. Finally, all of the amazing spatial software and tools developed by one of the most dedicated open source communities out there.
+
+
diff --git a/__tests__/controller.test.js b/__tests__/controller.test.js
new file mode 100644
index 000000000..2e22f0f40
--- /dev/null
+++ b/__tests__/controller.test.js
@@ -0,0 +1,22 @@
+import Controller from '../src/js/controller';
+
+describe('Controller', () => {
+
+ it('initialize successully', () => {
+ let controller = new Controller({});
+ });
+ describe('Event loop', () => {
+ it('adds the state to payload', () => {
+ let controller = new Controller({});
+ let result = null;
+ let payload = "expected"
+ controller.on('eventname', (e) => result = e)
+
+ controller.triggerEvent('eventname', payload);
+
+ expect(result).toHaveProperty('state')
+ expect(result).toHaveProperty('payload')
+ });
+ });
+});
+
diff --git a/__tests__/utils.test.js b/__tests__/utils.test.js
new file mode 100644
index 000000000..1dc2f6ac8
--- /dev/null
+++ b/__tests__/utils.test.js
@@ -0,0 +1,47 @@
+import {validation, defaultIfMissing} from '../src/js/utils';
+
+describe('Testing validation functions', () => {
+
+
+ test.each([
+ [null, true], [undefined, false], [{}, false],
+ ['', false], [NaN, false]])('.isNull(%s)', (value, expected) => {
+ expect(validation.isNull(value)).toBe(expected);
+ });
+
+ test.each([
+ [null, false], [undefined, true], [{}, false],
+ ['', false], [NaN, false]])('.isUndefined(%s)', (value, expected) => {
+ expect(validation.isUndefined(value)).toBe(expected);
+ });
+
+ test.each([
+ [null, false], [undefined, false], [{}, false],
+ ['', true], [NaN, false]])('.isEmptyString(%s)', (value, expected) => {
+ expect(validation.isEmptyString(value)).toBe(expected);
+ });
+
+ test.each([
+ [null, false], [undefined, false], [{}, true],
+ ['', false], [NaN, false]])('.isEmptyObject(%s)', (value, expected) => {
+ expect(validation.isEmptyObject(value)).toBe(expected);
+ });
+
+ test.each([
+ [null, true], [undefined, true], [{}, true],
+ ['', true], [5, false]])('.isMissingData(%s)', (value, expected) => {
+ expect(validation.isMissingData(value)).toBe(expected);
+ });
+});
+
+describe('Testing defaults', () => {
+ test('checkAny function works correctly', () => {
+ expect(defaultIfMissing(5, 5)).toBe(5);
+ expect(defaultIfMissing('XXX', 5)).toBe('XXX');
+ expect(defaultIfMissing(undefined, 5)).toBe(5);
+ expect(defaultIfMissing(null, 5)).toBe(5);
+ expect(defaultIfMissing({}, 5)).toBe(5);
+ expect(defaultIfMissing('', 5)).toBe(5);
+ })
+})
+
diff --git a/package.json b/package.json
index 6105bab7d..572c119c1 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
"d3-selection": "^1.4.1",
"data-visualisations": "https://github.com/vulekamali/data-visualisations.git#reusable",
"html2canvas": "^1.0.0-rc.5",
+ "jquery": "^3.5.1",
"js": "^0.1.0",
"leaflet": "~1.3.1",
"leaflet-event-forwarder": "^0.0.3",
@@ -29,20 +30,23 @@
},
"devDependencies": {
"@babel/cli": "^7.8.3",
- "@babel/core": "^7.0.0-0",
+ "@babel/core": "^7.11.6",
"@babel/plugin-proposal-class-properties": "^7.10.1",
- "@babel/preset-env": "^7.9.6",
+ "@babel/preset-env": "^7.11.5",
"babel-core": "^6.26.3",
+ "babel-jest": "^26.3.0",
"babel-loader": "^8.0.6",
"babel-plugin-transform-regenerator": "^6.26.0",
"babel-preset-env": "^1.7.0",
"cssnano": "^4.1.10",
+ "jest": "^26.4.2",
"parcel": "^1.12.4",
"parcel-bundler": "^1.12.4"
},
"scripts": {
"start": "parcel ./src/index.html",
- "test": "./run_test.sh",
+ "test": "jest",
+ "test:watch": "jest --watch",
"prebuild-dev": "shx rm -rf dist/*",
"build-dev": "parcel build ./src/index.html --no-minify --public-url ./",
"prebuild": "shx rm -rf dist/*",
@@ -51,5 +55,10 @@
"push-staging": "push-dir --remote=staging --dir=dist --branch=gh-pages --cleanup --verbose",
"clean-files": "cp dist/js*.js dist/wazimap-ng.js; cp dist/js*.js.map dist/wazimap-ng.js.map; cp dist/js*.css dist/wazimap-ng.css"
},
- "browserslist": "> 0.25%, not dead"
+ "browserslist": "> 0.25%, not dead",
+ "jest": {
+ "setupFiles": [
+ "./setup-jest.js"
+ ]
+ }
}
diff --git a/setup-jest.js b/setup-jest.js
new file mode 100644
index 000000000..b8b3275d7
--- /dev/null
+++ b/setup-jest.js
@@ -0,0 +1,2 @@
+import $ from 'jquery';
+global.$ = global.jQuery = $;
diff --git a/src/401.html b/src/401.html
index 235ef015a..6ab28ecb3 100644
--- a/src/401.html
+++ b/src/401.html
@@ -1,6 +1,6 @@
-
+