forked from nightscout/nightscout-connect
-
Notifications
You must be signed in to change notification settings - Fork 0
/
testable_driver.js
156 lines (134 loc) · 3.95 KB
/
testable_driver.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
*
* Roughly simulates network I/O via a Promise using setTimeout. These fail at
* much higher rates than in real life at every point, making it a kind of
* stress test for the actor logic.
*
* Real drivers would be expected to use axios.get and axios.post with suitable
* URLs, headers, content bodies to exchange credentials for a session and a
* session for up to date Nightscout data.
* There will also need to be a way to evalute gaps for Nightscout and pass the
* needed gap information into this in order to customize the query correctly.
*
* Injecting axios as a dependency will allow mocking using moxios, sinon or
* other tools.
*/
function fakeFrame (opts, axios) {
const impl = {
authFromCredentials(creds, settings) {
var delay = 200;
var probability = .2;
var maybeCredentials = new Promise((resolve, reject) => {
setTimeout(() => {
if (probability > Math.random( )) {
return reject({ type: 'auth', status: 500, msg: "foo"});
}
resolve("foo");
}, delay);
});
return maybeCredentials;
},
sessionFromAuth(auth, settings) {
var delay = 100;
var probability = .2;
var maybeSession= new Promise((resolve, reject) => {
setTimeout(() => {
if (probability > Math.random( )) {
return reject({ type: 'session', status: 500, msg: "foo"});
}
resolve(auth);
}, delay);
});
return maybeSession;
},
dataFromSesssion(session, settings) {
var delay = 300;
var probability = .5;
var maybeData = new Promise((resolve, reject) => {
setTimeout(() => {
if (probability > Math.random( )) {
return reject({ type: 'data', status: 500, msg: "foo"});
}
resolve({entries: [], treatments: [] });
}, delay);
});
return maybeData;
},
fakeTransformGlucose (data) {
console.log('MODIFY TRANSFORM GLUCOSE FAKE', data);
data.faked = true;
data.dateTime = (new Date()).toISOString();
data.date = (new Date()).getTime();
return data;
},
simulateBadCreds(ref) {
},
simulateGoodCreds(ref) {
},
simulateBadSession(ref) {
},
simulateGoodSession(ref) {
},
simulateBadData(ref) {
},
simulateGoodData(ref) {
},
};
/*
* Pass the driver a builder to describe how this driver exposes
* functionality.
*/
function generate_driver (builder) {
// it's common to need to build a session
builder.support_session({
authenticate: impl.authFromCredentials,
authorize: impl.sessionFromAuth,
// refresh: impl.refreshSession,
delays: {
REFRESH_AFTER_SESSSION_DELAY: 1600,
EXPIRE_SESSION_DELAY: 2200,
}
});
// some drivers have one loop every five minutes, some have others at
// varying hourly or daily intervals.
builder.register_loop('Cycle', {
frame: {
impl: impl.dataFromSesssion,
transform: impl.fakeTransformGlucose,
backoff: {
},
// transformer
maxRetries: 3
},
// expected_data_interval_ms: 5 * 60 * 1000
expected_data_interval_ms: 333,
backoff: {
interval_ms: 2500
},
});
// could be called multiple times
// builder.register_loop({ ...hourlyConfig });
builder.register_loop('AnotherLonger', {
frame: {
impl: impl.dataFromSesssion,
backoff: {
interval_ms: 3500
},
maxRetries: 3
},
// expected_data_interval_ms: 5 * 60 * 1000
expected_data_interval_ms: 2.3 * 60 * 1000,
backoff: {
interval_ms: 4500
},
});
return builder;
}
impl.generate_driver = generate_driver;
return impl;
// consider using class, but rejected; maybe in the builder?
function Factory ( ) { return this };
Object.assign(Factory.prototype, impl);
return new Factory( );
}
module.exports.fakeFrame = fakeFrame;