16 Commits

Author SHA1 Message Date
Linus Groh
988b10de40 Release 2.0.0-beta.7 2020-01-24 21:20:22 +00:00
Linus Groh
639e96cae8 Upgrade dependencies 2020-01-24 20:43:21 +00:00
Linus Groh
df3dcb60d8 Update year in LICENSE 2020-01-05 11:52:40 +00:00
Linus Groh
09ce3b7861 Lint code on Travis CI 2019-12-16 21:20:31 +00:00
Linus Groh
04f0b65480 Separate linting and formatting 2019-12-16 21:16:33 +00:00
Linus Groh
d3e3b82a13 Lint/format markdown files 2019-12-16 21:06:01 +00:00
Linus Groh
769185ee5a Set no-console/no-debugger to "warn" in dev mode 2019-12-16 20:24:15 +00:00
Linus Groh
7b6641e70d Add jsconfig.json 2019-12-16 19:35:17 +00:00
Linus Groh
2827d85865 Release 2.0.0-beta.6 2019-12-14 19:39:56 +00:00
Linus Groh
693947c064 Fix heatmap 2019-12-14 19:35:24 +00:00
Linus Groh
a31c048060 Release 2.0.0-beta.5 2019-12-14 17:13:13 +00:00
Linus Groh
1f2be0aeb9 Upgrade dependencies 2019-12-14 17:10:22 +00:00
Linus Groh
92401eb6b1 Add $config Vue instance property 2019-12-14 16:59:12 +00:00
Linus Groh
8d2f22d3de Use configured locale for timestamp formatting 2019-12-14 16:48:18 +00:00
Linus Groh
1d106e45da Add Leaflet popup close button bg color transition 2019-12-14 16:33:17 +00:00
Linus Groh
1f07ae9266 Improve accessibility
* More title attributes
* Usage of aria-hidden and role attributes
* Focus style improvements
* Text contrast improvements
2019-12-14 16:32:10 +00:00
26 changed files with 787 additions and 435 deletions

View File

@@ -5,8 +5,8 @@ module.exports = {
},
extends: ["plugin:vue/essential", "@vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "error" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
"no-console": process.env.NODE_ENV === "production" ? "error" : "warn",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn",
"prettier/prettier": [
"error",
{

View File

@@ -3,4 +3,6 @@ node_js:
- 10
cache: yarn
script:
- yarn lint:js
- yarn lint:md
- yarn test

View File

@@ -1,4 +1,30 @@
# 2.0.0-beta.4 (2019-12-14)
# Changelog
## 2.0.0-beta.7 (2020-01-24)
This release doesn't really affect end-users but greatly improves the development experience.
- Add `jsconfig.json`
- Set `no-console`/`no-debugger` to `"warn"` in dev mode
- Linting and formatting:
- Separate npm scripts for linting and formatting
- Lint/format Markdown files
- Run lint on Travis CI
- Upgrade dependencies
## 2.0.0-beta.6 (2019-12-14)
- Fix heatmap - the upgrade of `vue2-leaflet` from 2.2.1 to 2.3.0 added an `activated` attribute to layers causing the heatmap to not show
## 2.0.0-beta.5 (2019-12-14)
- Add Leaflet popup close button background color transition
- Add `$config` Vue instance property
- Improve accessibility
- Use configured locale for timestamp formatting
- Upgrade dependencies
## 2.0.0-beta.4 (2019-12-14)
- Add support for time selection
- New date/time picker component is properly translated/localised and keyboard accessible
@@ -7,7 +33,7 @@
- Fix missing translation of "[date] to [date]"
- Update i18n development notes in `README.md`
# 2.0.0-beta.3 (2019-12-13)
## 2.0.0-beta.3 (2019-12-13)
- Add i18 support (currently English and German, `locale` config option)
- Add custom checkbox focus style
@@ -18,7 +44,7 @@
- `README.md` enhancements
- Upgrade dependencies
# 2.0.0-beta.2 (2019-11-02)
## 2.0.0-beta.2 (2019-11-02)
- Add `onLocationChange.reloadHistory` config option
- Add Travis CI config
@@ -27,7 +53,7 @@
- Fix table of content links in config documentation
- Upgrade dependencies
# 2.0.0-beta.1 (2019-10-26)
## 2.0.0-beta.1 (2019-10-26)
- Convert codebase to Node.js based development workflow, including:
- Package management using yarn
@@ -53,12 +79,12 @@
- Add documentation for all configuration options.
- Add more configuration options, including setting the API base URL ([#4](https://github.com/owntracks/frontend/issues/4)) and hiding the `ping/ping` location ([#12](https://github.com/owntracks/frontend/issues/12)).
# 1.1.0 (2019-10-26)
## 1.1.0 (2019-10-26)
- Add support for Docker. [#7](https://github.com/owntracks/frontend/pull/7), [@sharkoz](https://github.com/sharkoz)
- Move project to the OwnTracks organisation on GitHub. [#8](https://github.com/owntracks/frontend/pull/8), [@jpmens](https://github.com/jpmens)
- Enable compression in nginx configuration used in Docker image. [#11](https://github.com/owntracks/frontend/pull/11), [@sharkoz](https://github.com/sharkoz)
# 1.0.0 (2019-06-18)
## 1.0.0 (2019-06-18)
- Initial release

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2019 Linus Groh
Copyright (c) 2019-2020 Linus Groh
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -46,7 +46,7 @@ Or you can use `docker-compose` (if you also run the OwnTracks Recorder with the
compose config, and the service is named `otrecorder`):
```yaml
version: '3'
version: "3"
services:
owntracks-ui:
@@ -95,7 +95,10 @@ See [`docs/config.md`](docs/config.md) for all available options.
- Run `yarn install` to install dependencies
- Run `yarn serve` to compile for development and start the hot-reload server
- Run `yarn lint` to lint and fix files
- Run `yarn lint:js` to lint JavaScript/Vue files
- Run `yarn lint:md` to lint Markdown files
- Run `yarn format:js` to format JavaScript/Vue files
- Run `yarn format:md` to format Markdown files
- Run `yarn test` to run unit tests
### CORS-Proxy
@@ -106,6 +109,7 @@ instance of OwnTracks for development without making changes to its CORS-Headers
```console
$ yarn cors-proxy
```
If you have [basic authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#Basic_authentication_scheme)
enabled, create a `.env` file with your credentials:
@@ -152,7 +156,6 @@ where German translations were added.
<img src="https://raw.githubusercontent.com/owntracks/frontend/master/docs/images/info.png" alt="Info">
</p>
## Contributing
Please feel free to open an issue and discuss your ideas and report bugs. If you think

View File

@@ -6,7 +6,7 @@ COPY . ./
RUN yarn build
FROM nginx:1.17-alpine
LABEL version="2.0.0-beta.4"
LABEL version="2.0.0-beta.7"
LABEL description="OwnTracks UI"
LABEL maintainer="Linus Groh <mail@linusgroh.de>"
ENV LISTEN_PORT=80 \

View File

@@ -362,7 +362,8 @@ and [this Wikipedia article](https://en.wikipedia.org/wiki/Tiled_web_map).
// Use dark HDPI tiles from Mapbox
window.owntracks.config = {
map: {
url: "https://api.mapbox.com/v4/mapbox.dark/{z}/{x}/{y}@2x.png?access_token=xxxxxxxxxxxxxxxx"
url:
"https://api.mapbox.com/v4/mapbox.dark/{z}/{x}/{y}@2x.png?access_token=xxxxxxxxxxxxxxxx"
}
};
```
@@ -456,9 +457,9 @@ Whether to enable verbose mode or not.
- Type: [`Boolean`]
- Default: `false`
[`Boolean`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[`Date`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
[`Number`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
[`Object`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
[`String`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
[CSS `<color>`]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
[`boolean`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
[`date`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
[`number`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number
[`object`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object
[`string`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String
[css `<color>`]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value

9
jsconfig.json Normal file
View File

@@ -0,0 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["node_modules"]
}

View File

@@ -1,6 +1,6 @@
{
"name": "owntracks-ui",
"version": "2.0.0-beta.4",
"version": "2.0.0-beta.7",
"author": {
"name": "Linus Groh",
"email": "mail@linusgroh.de"
@@ -8,49 +8,52 @@
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"cors-proxy": "node scripts/corsProxy.js",
"format:js": "vue-cli-service lint",
"format:md": "prettier --write '{*.md,docs/**/*.md,src/**/*.md}'",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
"lint:js": "vue-cli-service lint --no-fix",
"lint:md": "prettier --check '{*.md,docs/**/*.md,src/**/*.md}'",
"test": "vue-cli-service test:unit"
},
"dependencies": {
"clipboard-copy": "^3.1.0",
"core-js": "^3.4.8",
"core-js": "^3.6.4",
"deepmerge": "^4.2.2",
"leaflet": "^1.6.0",
"leaflet.heat": "^0.2.0",
"moment": "^2.24.0",
"vue": "^2.6.6",
"vue": "^2.6.11",
"vue-ctk-date-time-picker": "^2.4.0",
"vue-feather-icons": "^5.0.0",
"vue-i18n": "^8.0.0",
"vue-i18n": "^8.15.3",
"vue-js-modal": "^1.3.31",
"vue-outside-events": "^1.1.3",
"vue-router": "^3.1.3",
"vue2-leaflet": "^2.2.1",
"vue-router": "^3.1.5",
"vue2-leaflet": "^2.4.2",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.1.1",
"@vue/cli-plugin-eslint": "^4.1.1",
"@vue/cli-plugin-unit-jest": "^4.1.1",
"@vue/cli-service": "^4.1.1",
"@vue/cli-plugin-babel": "^4.1.2",
"@vue/cli-plugin-eslint": "^4.1.2",
"@vue/cli-plugin-unit-jest": "^4.1.2",
"@vue/cli-service": "^4.1.2",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "1.0.0-beta.30",
"@vue/test-utils": "1.0.0-beta.31",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^10.0.3",
"babel-jest": "^24.9.0",
"babel-jest": "^25.1.0",
"cors-anywhere": "^0.4.1",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^6.0.1",
"jest-fetch-mock": "^2.1.2",
"lint-staged": "^9.5.0",
"eslint": "^6.8.0",
"eslint-plugin-prettier": "^3.1.2",
"eslint-plugin-vue": "^6.1.2",
"jest-fetch-mock": "^3.0.1",
"lint-staged": "^10.0.2",
"moment-locales-webpack-plugin": "^1.1.2",
"node-sass": "^4.13.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-i18n": "^0.6.0",
"vue-template-compiler": "^2.5.21"
"node-sass": "^4.13.1",
"sass-loader": "^8.0.2",
"vue-cli-plugin-i18n": "^0.6.1",
"vue-template-compiler": "^2.6.11"
},
"license": "MIT",
"repository": {

View File

@@ -17,7 +17,6 @@
<script>
import { mapActions } from "vuex";
import config from "@/config";
import * as types from "@/store/mutation-types";
import { log } from "@/logging";
import AppHeader from "@/components/AppHeader";
@@ -30,7 +29,7 @@ export default {
created() {
document.documentElement.style.setProperty(
"--color-primary",
config.primaryColor
this.$config.primaryColor
);
this.populateStateFromQuery(this.$route.query);
this.loadData();

View File

@@ -24,7 +24,7 @@ const fetchApi = (path, params = {}) => {
const url = getApiUrl(path);
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]));
log("HTTP", `GET ${url.href}`);
return fetch(url).catch(error => log("HTTP", error, logLevels.ERROR));
return fetch(url.href).catch(error => log("HTTP", error, logLevels.ERROR));
};
/**

View File

@@ -13,7 +13,7 @@
</button>
</div>
<div class="nav-item">
<LayersIcon size="1x" />
<LayersIcon size="1x" aria-hidden="true" role="img" />
<Dropdown :label="$t('Layer settings')" :title="$t('Show/hide layers')">
<label v-for="option in layerSettingsOptions" :key="option.layer">
<input
@@ -31,12 +31,12 @@
</Dropdown>
</div>
<div class="nav-item">
<CalendarIcon size="1x" />
<CalendarIcon size="1x" aria-hidden="true" role="img" />
<VueCtkDateTimePicker
v-model="startDateTime"
:format="DATE_TIME_FORMAT"
:color="config.primaryColor"
:locale="config.locale"
:color="$config.primaryColor"
:locale="$config.locale"
:max-date="endDateTime"
:button-now-translation="$t('Now')"
>
@@ -50,8 +50,8 @@
<VueCtkDateTimePicker
v-model="endDateTime"
:format="DATE_TIME_FORMAT"
:color="config.primaryColor"
:locale="config.locale"
:color="$config.primaryColor"
:locale="$config.locale"
:min-date="startDateTime"
:button-now-translation="$t('Now')"
>
@@ -63,7 +63,7 @@
</VueCtkDateTimePicker>
</div>
<div class="nav-item">
<UserIcon size="1x" />
<UserIcon size="1x" aria-hidden="true" role="img" />
<select
v-model="selectedUser"
class="dropdown-button button"
@@ -78,7 +78,7 @@
</select>
</div>
<div v-if="selectedUser" class="nav-item">
<SmartphoneIcon size="1x" />
<SmartphoneIcon size="1x" aria-hidden="true" role="img" />
<select
v-model="selectedDevice"
class="dropdown-button button"
@@ -104,7 +104,11 @@
:title="$t('Download raw data')"
@click="$modal.show('download')"
>
<DownloadIcon size="1x" />
<DownloadIcon
size="1x"
:aria-label="$t('Download raw data')"
role="img"
/>
</button>
</div>
<div class="nav-item">
@@ -113,7 +117,7 @@
:title="$t('Information')"
@click="$modal.show('information')"
>
<InfoIcon size="1x" />
<InfoIcon size="1x" :aria-label="$t('Information')" role="img" />
</button>
</div>
</nav>
@@ -135,7 +139,6 @@ import VueCtkDateTimePicker from "vue-ctk-date-time-picker";
import "vue-ctk-date-time-picker/dist/vue-ctk-date-time-picker.css";
import Dropdown from "@/components/Dropdown";
import config from "@/config";
import { DATE_TIME_FORMAT } from "@/constants";
import * as types from "@/store/mutation-types";
@@ -153,7 +156,6 @@ export default {
data() {
return {
DATE_TIME_FORMAT,
config,
layerSettingsOptions: [
{ layer: "last", label: this.$t("Show last known locations") },
{ layer: "line", label: this.$t("Show location history (line)") },

View File

@@ -3,30 +3,30 @@
<div v-if="name" class="device">{{ name }}</div>
<div v-else class="device">{{ user }}/{{ device }}</div>
<div class="wrapper">
<img v-if="face" :src="faceImageDataURI" />
<img v-if="face" :src="faceImageDataURI" alt="" />
<ul class="info-list">
<li>
<ClockIcon size="1x" />
{{ new Date(timestamp * 1000).toLocaleString() }}
<li :title="$t('Timestamp')">
<ClockIcon size="1x" aria-hidden="true" role="img" />
{{ new Date(timestamp * 1000).toLocaleString($config.locale) }}
</li>
<li>
<MapPinIcon size="1x" />
<li :title="$t('Location')">
<MapPinIcon size="1x" aria-hidden="true" role="img" />
{{ lat }}
<br />
{{ lon }}
<br />
{{ alt }}m
</li>
<li v-if="address">
<HomeIcon size="1x" />
<li v-if="address" :title="$t('Address')">
<HomeIcon size="1x" aria-hidden="true" role="img" />
{{ address }}
</li>
<li v-if="typeof battery === 'number'">
<BatteryIcon size="1x" />
<li v-if="typeof battery === 'number'" :title="$t('Battery')">
<BatteryIcon size="1x" aria-hidden="true" role="img" />
{{ battery }} %
</li>
<li v-if="typeof speed === 'number'">
<ZapIcon size="1x" />
<li v-if="typeof speed === 'number'" :title="$t('Speed')">
<ZapIcon size="1x" aria-hidden="true" role="img" />
{{ speed }} km/h
</li>
</ul>

View File

@@ -58,6 +58,11 @@ const props = {
custom: true,
default: true,
},
activated: {
type: Boolean,
custom: true,
default: true,
},
};
export default {

View File

@@ -12,10 +12,18 @@
</label>
</div>
<div class="buttons">
<button class="button button-outline button-primary" @click="copy">
<button
class="button button-outline button-primary"
:title="$t('Copy to clipboard')"
@click="copy"
>
{{ $t("Copy to clipboard") }}
</button>
<button class="button button-primary" @click="download">
<button
class="button button-primary"
:title="$t('Download')"
@click="download"
>
{{ $t("Download") }}
</button>
</div>

View File

@@ -2,33 +2,33 @@
<modal name="information" adaptive>
<ul class="info-list">
<li>
<GithubIcon size="1x" />
<GithubIcon size="1x" aria-hidden="true" role="img" />
<a href="https://github.com/owntracks/frontend">
owntracks/frontend
</a>
({{ frontendVersion }})
</li>
<li>
<GithubIcon size="1x" />
<GithubIcon size="1x" aria-hidden="true" role="img" />
<a href="https://github.com/owntracks/recorder">
owntracks/recorder
</a>
({{ recorderVersion || "Loading version..." }})
</li>
<li>
<GlobeIcon size="1x" />
<GlobeIcon size="1x" aria-hidden="true" role="img" />
<a href="https://owntracks.org">
{{ $t("OwnTracks website") }}
</a>
</li>
<li>
<BookIcon size="1x" />
<BookIcon size="1x" aria-hidden="true" role="img" />
<a href="https://owntracks.org/booklet/">
{{ $t("OwnTracks documentation") }}
</a>
</li>
<li>
<TwitterIcon size="1x" />
<TwitterIcon size="1x" aria-hidden="true" role="img" />
<a href="https://twitter.com/OwnTracks">
{{ $t("OwnTracks on Twitter") }}
</a>

View File

@@ -22,5 +22,10 @@
"OwnTracks website": "OwnTracks Webseite",
"OwnTracks documentation": "OwnTracks Dokumentation",
"OwnTracks on Twitter": "OwnTracks auf Twitter",
"Loading data, please wait...": "Daten werden geladen, bitte warten..."
"Loading data, please wait...": "Daten werden geladen, bitte warten...",
"Timestamp": "Zeitstempel",
"Location": "Standort",
"Address": "Adresse",
"Battery": "Akku",
"Speed": "Geschwindigkeit"
}

View File

@@ -22,5 +22,10 @@
"OwnTracks website": "OwnTracks website",
"OwnTracks documentation": "OwnTracks documentation",
"OwnTracks on Twitter": "OwnTracks on Twitter",
"Loading data, please wait...": "Loading data, please wait..."
"Loading data, please wait...": "Loading data, please wait...",
"Timestamp": "Timestamp",
"Location": "Location",
"Address": "Address",
"Battery": "Battery",
"Speed": "Speed"
}

View File

@@ -1,5 +1,6 @@
import Vue from "vue";
import App from "@/App.vue";
import config from "@/config";
import i18n from "@/i18n";
import router from "@/router";
import store from "@/store";
@@ -11,6 +12,8 @@ Vue.use(VOutsideEvents);
Vue.config.productionTip = false;
Vue.prototype.$config = config;
new Vue({
i18n,
router,

View File

@@ -172,14 +172,20 @@ pre {
padding: 8px 16px;
text-overflow: ellipsis;
white-space: nowrap;
transition: box-shadow 0.2s;
&:focus {
outline: none;
box-shadow: 0 0 0 5px rgba(0, 0, 0, 0.2);
}
&:focus::-moz-focus-inner {
border-color: transparent;
}
&.button-primary {
color: var(--color-primary-text);
background: var(--color-primary);
&:focus::-moz-focus-inner {
border-color: var(--color-primary-text)e;
}
}
&.button-outline {
@@ -204,7 +210,8 @@ pre {
&.button-outline,
&.button-flat {
transition: background 0.2s;
transition: background-color 0.2s, box-shadow 0.2s;
&:hover,
&:focus {
background: rgba(0, 0, 0, 0.2);

View File

@@ -5,5 +5,6 @@
.datepicker {
box-shadow: none !important;
filter: var(--drop-shadow);
margin-top: 5px;
}
}

View File

@@ -23,6 +23,7 @@
margin-top: 15px;
margin-right: 15px;
border-radius: 100px;
transition: background-color 0.2s;
&:hover,
&:focus {
@@ -35,4 +36,12 @@
.leaflet-popup-tip {
box-shadow: none;
}
.leaflet-control-container .leaflet-control-attribution {
background: var(--color-background);
a {
color: var(--color-primary);
}
}
}

View File

@@ -118,7 +118,6 @@ import markerIcon2x from "leaflet/dist/images/marker-icon-2x.png";
import markerShadow from "leaflet/dist/images/marker-shadow.png";
import * as types from "@/store/mutation-types";
import config from "@/config";
import LHeatmap from "@/components/LHeatmap";
import LDeviceLocationPopup from "@/components/LDeviceLocationPopup";
@@ -145,26 +144,27 @@ export default {
},
data() {
return {
attribution: config.map.attribution,
attribution: this.$config.map.attribution,
center: this.$store.state.map.center,
controls: config.map.controls,
heatmap: config.map.heatmap,
maxZoom: config.map.maxZoom,
maxNativeZoom: config.map.maxNativeZoom,
url: config.map.url,
controls: this.$config.map.controls,
heatmap: this.$config.map.heatmap,
maxZoom: this.$config.map.maxZoom,
maxNativeZoom: this.$config.map.maxNativeZoom,
url: this.$config.map.url,
zoom: this.$store.state.map.zoom,
circle: {
...config.map.circle,
color: config.map.circle.color || config.primaryColor,
fillColor: config.map.circle.fillColor || config.primaryColor,
...this.$config.map.circle,
color: this.$config.map.circle.color || this.$config.primaryColor,
fillColor:
this.$config.map.circle.fillColor || this.$config.primaryColor,
},
circleMarker: {
...config.map.circleMarker,
color: config.map.circleMarker.color || config.primaryColor,
...this.$config.map.circleMarker,
color: this.$config.map.circleMarker.color || this.$config.primaryColor,
},
polyline: {
...config.map.polyline,
color: config.map.polyline.color || config.primaryColor,
...this.$config.map.polyline,
color: this.$config.map.polyline.color || this.$config.primaryColor,
},
};
},

View File

@@ -12,9 +12,7 @@ describe("API", () => {
expect(version).toBe("1.2.3");
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0].href).toEqual(
"http://localhost/api/0/version"
);
expect(fetch.mock.calls[0][0]).toEqual("http://localhost/api/0/version");
});
test("getUsers", async () => {
@@ -24,7 +22,7 @@ describe("API", () => {
expect(users).toEqual(["foo", "bar"]);
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0].href).toEqual("http://localhost/api/0/list");
expect(fetch.mock.calls[0][0]).toEqual("http://localhost/api/0/list");
});
test("getDevices", async () => {
@@ -37,10 +35,10 @@ describe("API", () => {
expect(devices).toEqual({ foo: ["phone", "tablet"], bar: ["laptop"] });
expect(fetch.mock.calls.length).toEqual(2);
expect(fetch.mock.calls[0][0].href).toEqual(
expect(fetch.mock.calls[0][0]).toEqual(
"http://localhost/api/0/list?user=foo"
);
expect(fetch.mock.calls[1][0].href).toEqual(
expect(fetch.mock.calls[1][0]).toEqual(
"http://localhost/api/0/list?user=bar"
);
});
@@ -68,7 +66,7 @@ describe("API", () => {
expect(lastLocation).toEqual(response);
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0].href).toEqual("http://localhost/api/0/last");
expect(fetch.mock.calls[0][0]).toEqual("http://localhost/api/0/last");
});
test("getLastLocations with user", async () => {
@@ -89,7 +87,7 @@ describe("API", () => {
expect(lastLocation).toEqual(response);
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0].href).toEqual(
expect(fetch.mock.calls[0][0]).toEqual(
"http://localhost/api/0/last?user=foo"
);
});
@@ -108,7 +106,7 @@ describe("API", () => {
expect(lastLocation).toEqual(response);
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0].href).toEqual(
expect(fetch.mock.calls[0][0]).toEqual(
"http://localhost/api/0/last?user=foo&device=phone"
);
});
@@ -150,7 +148,7 @@ describe("API", () => {
expect(locationHistory).toEqual(response.data);
expect(fetch.mock.calls.length).toEqual(1);
expect(fetch.mock.calls[0][0].href).toEqual(
expect(fetch.mock.calls[0][0]).toEqual(
"http://localhost/api/0/locations?from=1970-01-01T00%3A00%3A00&to=1970-12-31T23%3A59%3A59&user=foo&device=phone&format=json"
);
});
@@ -206,13 +204,13 @@ describe("API", () => {
});
expect(fetch.mock.calls.length).toEqual(3);
expect(fetch.mock.calls[0][0].href).toEqual(
expect(fetch.mock.calls[0][0]).toEqual(
"http://localhost/api/0/locations?from=1970-01-01T00%3A00%3A00&to=1970-12-31T23%3A59%3A59&user=foo&device=phone&format=json"
);
expect(fetch.mock.calls[1][0].href).toEqual(
expect(fetch.mock.calls[1][0]).toEqual(
"http://localhost/api/0/locations?from=1970-01-01T00%3A00%3A00&to=1970-12-31T23%3A59%3A59&user=foo&device=tablet&format=json"
);
expect(fetch.mock.calls[2][0].href).toEqual(
expect(fetch.mock.calls[2][0]).toEqual(
"http://localhost/api/0/locations?from=1970-01-01T00%3A00%3A00&to=1970-12-31T23%3A59%3A59&user=bar&device=laptop&format=json"
);
});

View File

@@ -1 +1 @@
global.fetch = require("jest-fetch-mock");
require("jest-fetch-mock").enableMocks();

914
yarn.lock

File diff suppressed because it is too large Load Diff