Fix login auto-retry deadlock
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const http = require('node:http');
|
||||
const test = require('node:test');
|
||||
|
||||
const { AgrarmonitorConnector, MemoryCookieStore } = require('../dist');
|
||||
|
||||
const loginPage = `
|
||||
<html>
|
||||
<head><title>Anmeldung - AGRARMONITOR</title></head>
|
||||
<body>
|
||||
<form>
|
||||
<input name="nonce" value="test-nonce" />
|
||||
<button>Einloggen</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
function createServer() {
|
||||
let loggedIn = false;
|
||||
const requests = [];
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
requests.push({ method: req.method, url: req.url });
|
||||
|
||||
if (req.method === 'GET' && req.url === '/') {
|
||||
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
||||
res.end(loggedIn ? '<html><body>Mein AM</body></html>' : loginPage);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method === 'POST' && req.url === '/login/api/login.php') {
|
||||
let body = '';
|
||||
req.on('data', chunk => {
|
||||
body += chunk;
|
||||
});
|
||||
req.on('end', () => {
|
||||
const parsed = JSON.parse(body);
|
||||
assert.equal(req.headers['content-type'], 'application/json');
|
||||
assert.equal(parsed.username, 'demo');
|
||||
assert.equal(parsed.passwort, 'secret');
|
||||
assert.equal(parsed.nonce, 'test-nonce');
|
||||
assert.equal(parsed.ssoAction, '');
|
||||
assert.equal(parsed.ssoReturn, '');
|
||||
|
||||
loggedIn = true;
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json',
|
||||
'Set-Cookie': 'agrar_session=test; Path=/',
|
||||
});
|
||||
res.end(JSON.stringify({ success: true }));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(404);
|
||||
res.end('not found');
|
||||
});
|
||||
|
||||
return { server, requests };
|
||||
}
|
||||
|
||||
test('autoRetry does not deadlock on login-internal requests', async t => {
|
||||
const { server, requests } = createServer();
|
||||
|
||||
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
|
||||
t.after(() => new Promise(resolve => server.close(resolve)));
|
||||
|
||||
const address = server.address();
|
||||
const baseUrl = `http://127.0.0.1:${address.port}`;
|
||||
|
||||
const connector = new AgrarmonitorConnector({
|
||||
baseUrl,
|
||||
username: 'demo',
|
||||
password: 'secret',
|
||||
cookieStore: new MemoryCookieStore(),
|
||||
});
|
||||
|
||||
const timeout = new Promise((_, reject) => {
|
||||
const timer = setTimeout(() => reject(new Error('Login deadlocked')), 2000);
|
||||
timer.unref();
|
||||
});
|
||||
|
||||
await Promise.race([connector.init(), timeout]);
|
||||
|
||||
const response = await Promise.race([connector.http.get('/'), timeout]);
|
||||
assert.equal(response.status, 200);
|
||||
assert.equal(requests.filter(request => request.url === '/login/api/login.php').length, 1);
|
||||
assert.ok(requests.filter(request => request.method === 'GET' && request.url === '/').length >= 3);
|
||||
});
|
||||
Reference in New Issue
Block a user