Skip to content

Commit 8d4fd92

Browse files
committed
WIP: add crawler_support.test.ts
1 parent 619fafb commit 8d4fd92

File tree

3 files changed

+254
-1
lines changed

3 files changed

+254
-1
lines changed

gulp/tasks/dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const testFxns = require('./test');
2222
function watchDevFiles() {
2323
const stream = gulp.watch([
2424
`${config.root}/src/**/*.ts`,
25-
config.paths.test.unit
25+
'tests/**/*.test.ts'
2626
], testFxns.runBrowserUnitTests(true));
2727

2828
stream.on('error', err => {});
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
import { expect } from "chai";
2+
import { forceRestClient } from "../../../src/database/api/test_access";
3+
4+
import {
5+
getRandomNode,
6+
testAuthTokenProvider,
7+
getFreshRepoFromReference
8+
} from "../helpers/util";
9+
10+
// Some sanity checks for the ReadonlyRestClient crawler support.
11+
describe('Crawler Support', function() {
12+
var initialData;
13+
var normalRef;
14+
var restRef;
15+
var tokenProvider;
16+
17+
beforeEach(function(done) {
18+
normalRef = getRandomNode();
19+
20+
forceRestClient(true);
21+
restRef = getFreshRepoFromReference(normalRef);
22+
forceRestClient(false);
23+
24+
tokenProvider = testAuthTokenProvider(restRef.database.app);
25+
26+
setInitialData(done);
27+
});
28+
29+
afterEach(function() {
30+
tokenProvider.setToken(null);
31+
});
32+
33+
function setInitialData(done) {
34+
// Set some initial data.
35+
initialData = {
36+
leaf: 42,
37+
securedLeaf: 'secret',
38+
leafWithPriority: { '.value': 42, '.priority': 'pri' },
39+
obj: { a: 1, b: 2 },
40+
list: {
41+
10: { name: 'amy', age: 75, '.priority': 22 },
42+
20: { name: 'becky', age: 42, '.priority': 52 },
43+
30: { name: 'fred', age: 35, '.priority': 23 },
44+
40: { name: 'fred', age: 29, '.priority': 26 },
45+
50: { name: 'sally', age: 21, '.priority': 96 },
46+
60: { name: 'tom', age: 16, '.priority': 15 },
47+
70: { name: 'victor', age: 4, '.priority': 47 }
48+
},
49+
valueList: {
50+
10: 'c',
51+
20: 'b',
52+
30: 'e',
53+
40: 'f',
54+
50: 'a',
55+
60: 'd',
56+
70: 'e'
57+
}
58+
};
59+
60+
normalRef.set(initialData, function(error) {
61+
expect(error).to.equal(null);
62+
done();
63+
});
64+
}
65+
66+
it('set() is a no-op', function(done) {
67+
// This test mostly exists to make sure restRef really is using ReadonlyRestClient
68+
// and we're not accidentally testing a normal Firebase connection. It also can
69+
// be a little slow so adding an extra timeout to help out.
70+
this.timeout(3500);
71+
72+
normalRef.child('leaf').on('value', function(s) {
73+
expect(s.val()).to.equal(42);
74+
});
75+
76+
restRef.child('leaf').set('hello');
77+
78+
// We need to wait long enough to be sure that our 'hello' didn't actually get set, but there's
79+
// no good way to do that. So we just do a couple round-trips via the REST client and assume
80+
// that's good enough.
81+
restRef.child('obj').once('value', function(s) {
82+
expect(s.val()).to.deep.equal(initialData.obj);
83+
84+
restRef.child('obj').once('value', function(s) {
85+
expect(s.val()).to.deep.equal(initialData.obj);
86+
87+
normalRef.child('leaf').off();
88+
done();
89+
});
90+
});
91+
});
92+
93+
it('set() is a no-op (Promise)', function() {
94+
// This test mostly exists to make sure restRef really is using ReadonlyRestClient
95+
// and we're not accidentally testing a normal Firebase connection.
96+
97+
normalRef.child('leaf').on('value', function(s) {
98+
expect(s.val()).to.equal(42);
99+
});
100+
101+
restRef.child('leaf').set('hello');
102+
103+
// We need to wait long enough to be sure that our 'hello' didn't actually get set, but there's
104+
// no good way to do that. So we just do a couple round-trips via the REST client and assume
105+
// that's good enough.
106+
return restRef.child('obj').once('value').then(function(s) {
107+
expect(s.val()).to.deep.equal(initialData.obj);
108+
109+
return restRef.child('obj').once('value');
110+
}).then(function(s) {
111+
expect(s.val()).to.deep.equal(initialData.obj);
112+
normalRef.child('leaf').off();
113+
}, function (reason) {
114+
normalRef.child('leaf').off();
115+
return Promise.reject(reason);
116+
});
117+
});
118+
119+
it('.info/connected fires with true', function(done) {
120+
restRef.root.child('.info/connected').on('value', function(s) {
121+
if (s.val() == true) {
122+
done();
123+
}
124+
});
125+
});
126+
127+
it('Leaf read works.', function(done) {
128+
restRef.child('leaf').once('value', function(s) {
129+
expect(s.val()).to.equal(initialData.leaf);
130+
done();
131+
});
132+
});
133+
134+
it('Leaf read works. (Promise)', function() {
135+
return restRef.child('leaf').once('value').then(function(s) {
136+
expect(s.val()).to.equal(initialData.leaf);
137+
});
138+
});
139+
140+
it('Object read works.', function(done) {
141+
restRef.child('obj').once('value', function(s) {
142+
expect(s.val()).to.deep.equal(initialData.obj);
143+
done();
144+
});
145+
});
146+
147+
it('Object read works. (Promise)', function() {
148+
return restRef.child('obj').once('value').then(function(s) {
149+
expect(s.val()).to.deep.equal(initialData.obj);
150+
});
151+
});
152+
153+
it('Leaf with priority read works.', function(done) {
154+
restRef.child('leafWithPriority').once('value', function(s) {
155+
expect(s.exportVal()).to.deep.equal(initialData.leafWithPriority);
156+
done();
157+
});
158+
});
159+
160+
it('Leaf with priority read works. (Promise)', function() {
161+
return restRef.child('leafWithPriority').once('value').then(function(s) {
162+
expect(s.exportVal()).to.deep.equal(initialData.leafWithPriority);
163+
});
164+
});
165+
166+
it('Null read works.', function(done) {
167+
restRef.child('nonexistent').once('value', function(s) {
168+
expect(s.val()).to.equal(null);
169+
done();
170+
});
171+
});
172+
173+
it('Null read works. (Promise)', function() {
174+
return restRef.child('nonexistent').once('value').then(function(s) {
175+
expect(s.val()).to.equal(null);
176+
});
177+
});
178+
179+
it('on works.', function(done) {
180+
restRef.child('leaf').on('value', function(s) {
181+
expect(s.val()).to.equal(initialData.leaf);
182+
restRef.child('leaf').off();
183+
done();
184+
});
185+
});
186+
});

tests/database/helpers/util.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,71 @@ export function shuffle(arr, randFn?) {
113113
arr[i] = arr[j];
114114
arr[j] = tmp;
115115
}
116+
}
117+
118+
export function testAuthTokenProvider(app) {
119+
var token_ = null;
120+
var nextToken_ = null;
121+
var hasNextToken_ = false;
122+
var listeners_ = [];
123+
124+
app['INTERNAL'] = app['INTERNAL'] || {};
125+
126+
app['INTERNAL']['getToken'] = function(forceRefresh) {
127+
if (forceRefresh && hasNextToken_) {
128+
token_ = nextToken_;
129+
hasNextToken_ = false;
130+
}
131+
return Promise.resolve({accessToken: token_});
132+
};
133+
134+
app['INTERNAL']['addAuthTokenListener'] = function(listener) {
135+
var token = token_;
136+
listeners_.push(listener);
137+
var async = Promise.resolve();
138+
async.then(function() {
139+
listener(token)
140+
});
141+
};
142+
143+
app['INTERNAL']['removeAuthTokenListener'] = function(listener) {
144+
throw Error('removeAuthTokenListener not supported in testing');
145+
};
146+
147+
return {
148+
setToken: function(token) {
149+
token_ = token;
150+
var async = Promise.resolve();
151+
for (var i = 0; i < listeners_.length; i++) {
152+
async.then((function(idx) {
153+
return function() {
154+
listeners_[idx](token);
155+
}
156+
}(i)));
157+
}
158+
159+
// Any future thens are guaranteed to be resolved after the listeners have been notified
160+
return async;
161+
},
162+
setNextToken: function(token) {
163+
nextToken_ = token;
164+
hasNextToken_ = true;
165+
}
166+
};
167+
}
168+
169+
let freshRepoId = 1;
170+
const activeFreshApps = [];
171+
172+
export function getFreshRepo(url, path) {
173+
var app = firebase.initializeApp({databaseURL: url}, 'ISOLATED_REPO_' + freshRepoId++);
174+
patchFakeAuthFunctions(app);
175+
activeFreshApps.push(app);
176+
return app.database().ref(path);
177+
}
178+
179+
export function getFreshRepoFromReference(ref) {
180+
var host = ref.root.toString();
181+
var path = ref.toString().replace(host, '');
182+
return getFreshRepo(host, path);
116183
}

0 commit comments

Comments
 (0)