@wemap/routers 12.7.2 → 12.7.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "directory": "packages/routers"
13
13
  },
14
14
  "name": "@wemap/routers",
15
- "version": "12.7.2",
15
+ "version": "12.7.3",
16
16
  "bugs": {
17
17
  "url": "https://github.com/wemap/wemap-modules-js/issues"
18
18
  },
@@ -52,5 +52,5 @@
52
52
  },
53
53
  "./helpers/*": "./helpers/*"
54
54
  },
55
- "gitHead": "ea4c02ed0fce8e59634b86c123464116fcd9eace"
55
+ "gitHead": "67ad72998468c84862793eb326649b6923b0f6ec"
56
56
  }
@@ -0,0 +1,178 @@
1
+ import chai from 'chai';
2
+ import chaiAlmost from 'chai-almost';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+ import fetchMock from 'fetch-mock';
7
+
8
+ import { Coordinates } from '@wemap/geo';
9
+
10
+ import RemoteRouterManager, { RoutingFallbackStrategy } from './RemoteRouterManager.js';
11
+ import { RemoteRoutingError } from '../RoutingError.js';
12
+
13
+ type MockAny = any;
14
+
15
+ const { expect } = chai;
16
+ chai.use(chaiAlmost(0.1));
17
+
18
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
+ const assetsPath = path.resolve(__dirname, '../../assets');
20
+ const osrmPath = path.resolve(assetsPath, 'itinerary-montpellier-outdoor.json');
21
+ const osrmJson = JSON.parse(fs.readFileSync(osrmPath, 'utf8'));
22
+
23
+ describe('RemoteRouterManager', () => {
24
+ afterEach(() => {
25
+ fetchMock.restore();
26
+ });
27
+
28
+ describe('getRouterByName', () => {
29
+ it('should return the router', () => {
30
+ const router = RemoteRouterManager.getRouterByName('osrm');
31
+ expect(router).not.null;
32
+ });
33
+
34
+ it('should return undefined if router is unknown', () => {
35
+ const router = RemoteRouterManager.getRouterByName('unknown' as MockAny);
36
+
37
+ expect(router).to.be.undefined;
38
+ });
39
+ });
40
+
41
+ describe('getItineraries', () => {
42
+ it('should return itineraries', async () => {
43
+ fetchMock.mock('*', (() => {
44
+ return osrmJson;
45
+ })())
46
+
47
+ const routerRequest = {
48
+ origin: new Coordinates(48.8725992, 2.343431),
49
+ destination: new Coordinates(48.8725694, 2.3433),
50
+ travelMode: 'WALK'
51
+ } as const;
52
+
53
+ const itineraries = await RemoteRouterManager.getItineraries('osrm', 'http://localhost:3001', routerRequest);
54
+ expect(itineraries).not.empty;
55
+ });
56
+
57
+ it('should throw an error if router is unknown', (done) => {
58
+ const routerRequest = {
59
+ origin: new Coordinates(48.8725992, 2.343431),
60
+ destination: new Coordinates(48.8725694, 2.3433),
61
+ travelMode: 'WALK'
62
+ } as const;
63
+
64
+ RemoteRouterManager.getItineraries('unknown' as MockAny, 'http://localhost:3001', routerRequest)
65
+ .then(() => done('should throw an error'))
66
+ .catch(() => done());
67
+ });
68
+
69
+ it('should throw an error on server error', (done) => {
70
+ fetchMock.mock('*', (() => {
71
+ return new Response(null, { status: 404 });
72
+ })())
73
+
74
+ const routerRequest = {
75
+ origin: new Coordinates(48.8725992, 2.343431),
76
+ destination: new Coordinates(48.8725694, 2.3433),
77
+ travelMode: 'WALK'
78
+ } as const;
79
+
80
+ RemoteRouterManager.getItineraries('unknown' as MockAny, 'http://localhost:3001', routerRequest)
81
+ .then(() => done('should throw an error'))
82
+ .catch(() => done());
83
+ });
84
+ });
85
+
86
+ describe('getItinerariesWithFallback', () => {
87
+ it('should return itineraries', async () => {
88
+ fetchMock.mock('*', (() => {
89
+ return osrmJson;
90
+ })())
91
+
92
+ const routerRequest = {
93
+ origin: new Coordinates(48.8725992, 2.343431),
94
+ destination: new Coordinates(48.8725694, 2.3433),
95
+ travelMode: 'WALK'
96
+ } as const;
97
+
98
+ const fallbackStrategy: RoutingFallbackStrategy = [
99
+ { name: 'osrm', endpointUrl: 'http://localhost:3001' }
100
+ ];
101
+
102
+ const itineraries = await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);
103
+ expect(itineraries).not.empty;
104
+ });
105
+
106
+ it('should throw an error if all routers are unknown', (done) => {
107
+ const routerRequest = {
108
+ origin: new Coordinates(48.8725992, 2.343431),
109
+ destination: new Coordinates(48.8725694, 2.3433),
110
+ travelMode: 'WALK'
111
+ } as const;
112
+
113
+ const fallbackStrategy = [
114
+ { name: 'unknown' as MockAny, endpointUrl: 'http://localhost:3001/unknown' }
115
+ ];
116
+
117
+ RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy)
118
+ .then(() => done('should throw an error'))
119
+ .catch((error) => {
120
+ expect(error instanceof RemoteRoutingError).to.be.true;
121
+ expect((error as RemoteRoutingError).routerName).equal('unknown');
122
+ expect((error as RemoteRoutingError).message).to.contains('http://localhost:3001/unknown');
123
+
124
+ done();
125
+ });
126
+ });
127
+
128
+ it('should throw an error if all routers are unreachable and return all errors', (done) => {
129
+ fetchMock.mock('*', (() => {
130
+ return new Response(null, { status: 404 });
131
+ })())
132
+
133
+ const routerRequest = {
134
+ origin: new Coordinates(48.8725992, 2.343431),
135
+ destination: new Coordinates(48.8725694, 2.3433),
136
+ travelMode: 'WALK'
137
+ } as const;
138
+
139
+ const fallbackStrategy = [
140
+ { name: 'osrm', endpointUrl: 'http://localhost:3001/osrm' },
141
+ { name: 'unknown' as MockAny, endpointUrl: 'http://localhost:3001/unknown' }
142
+ ];
143
+
144
+ RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy)
145
+ .then(() => done('should throw an error'))
146
+ .catch((error) => {
147
+ expect(error instanceof RemoteRoutingError).to.be.true;
148
+ expect((error as RemoteRoutingError).routerName).equal('osrm, unknown');
149
+ expect((error as RemoteRoutingError).message).to.contains('http://localhost:3001/osrm');
150
+ expect((error as RemoteRoutingError).message).to.contains('http://localhost:3001/unknown');
151
+
152
+ done();
153
+ });
154
+ });
155
+
156
+ it('should return itineraries and use fallback router if previous one fails', async () => {
157
+ fetchMock.mock('*', (() => {
158
+ return osrmJson;
159
+ })())
160
+
161
+ const routerRequest = {
162
+ origin: new Coordinates(48.8725992, 2.343431),
163
+ destination: new Coordinates(48.8725694, 2.3433),
164
+ travelMode: 'WALK'
165
+ } as const;
166
+
167
+ const fallbackStrategy = [
168
+ { name: 'unknown' as MockAny, endpointUrl: 'http://localhost:3001/unknown' },
169
+ { name: 'osrm', endpointUrl: 'http://localhost:3001/osrm' }
170
+ ];
171
+
172
+ const itineraries = await RemoteRouterManager.getItinerariesWithFallback(routerRequest, fallbackStrategy);
173
+ expect(itineraries).not.empty;
174
+ });
175
+
176
+ });
177
+
178
+ });
@@ -40,15 +40,30 @@ class RemoteRouterManager {
40
40
 
41
41
  async getItinerariesWithFallback(routerRequest: RouterRequest, fallbackStrategy: RoutingFallbackStrategy) {
42
42
  let itineraries;
43
+ const errors = [];
43
44
  for (const { name, endpointUrl } of fallbackStrategy) {
44
- itineraries = await this.getItineraries(name, endpointUrl, routerRequest);
45
- if (itineraries.length) {
46
- return itineraries;
45
+ try {
46
+ itineraries = await this.getItineraries(name, endpointUrl, routerRequest);
47
+ if (itineraries.length) {
48
+ return itineraries;
49
+ }
50
+ } catch (error) {
51
+ if (error instanceof RemoteRoutingError) {
52
+ errors.push({
53
+ name,
54
+ endpointUrl,
55
+ error
56
+ });
57
+ } else {
58
+ throw error;
59
+ }
47
60
  }
48
61
  }
49
62
 
50
- const routersNames = fallbackStrategy.map(({ name }) => name).join(',');
51
- throw RemoteRoutingError.notFound(routersNames, `Could not find an itinerary with any of following servers: ${routersNames}`)
63
+ const routersNames = fallbackStrategy.map(({ name }) => name).join(', ');
64
+ const errorsMessages = errors.map(routerError => `(${routerError.name}) Could not find an itinerary on endpoint: ${routerError.endpointUrl}. Details: ${routerError.error.message}`).join('\n');
65
+
66
+ throw RemoteRoutingError.notFound(routersNames, errorsMessages)
52
67
  }
53
68
  }
54
69