Fixup tests.

This commit is contained in:
Half-Shot 2024-04-16 22:31:13 +01:00
parent 6157fbccff
commit f2d97af122
2 changed files with 62 additions and 30 deletions

View File

@ -200,29 +200,38 @@ pub async fn js_read_feed(url: String, options: ReadFeedOptions) -> Result<FeedR
headers.append("If-None-Match", HeaderValue::from_str(&etag).unwrap()); headers.append("If-None-Match", HeaderValue::from_str(&etag).unwrap());
} }
let max_content_size = (options.maximum_feed_size_mb * 1024 * 1024) as u64;
match req.headers(headers).send().await { match req.headers(headers).send().await {
Ok(res) => { Ok(res) => {
// Pre-emptive check
let content_length = res.content_length().unwrap_or(0); let content_length = res.content_length().unwrap_or(0);
if content_length > (options.maximum_feed_size_mb * 1024 * 1024) as u64 { if content_length > max_content_size {
return Err(JsError::new(Status::Unknown, "Feed exceeded maximum size")); return Err(JsError::new(Status::Unknown, "Feed exceeded maximum size"));
} }
let res_headers = res.headers().clone(); let res_headers = res.headers().clone();
match res.status() { match res.status() {
StatusCode::OK => match res.text().await { StatusCode::OK => match res.text().await {
Ok(body) => match js_parse_feed(body) { Ok(body) => {
Ok(feed) => Ok(FeedResult { // Check if we only got the length after loading the response.
feed: Some(feed), match body.len() as u64 <= max_content_size {
etag: res_headers true => match js_parse_feed(body) {
.get("ETag") Ok(feed) => Ok(FeedResult {
.map(|v| v.to_str().unwrap()) feed: Some(feed),
.map(|v| v.to_string()), etag: res_headers
last_modified: res_headers .get("ETag")
.get("Last-Modified") .map(|v| v.to_str().unwrap())
.map(|v| v.to_str().unwrap()) .map(|v| v.to_string()),
.map(|v| v.to_string()), last_modified: res_headers
}), .get("Last-Modified")
Err(err) => Err(err), .map(|v| v.to_str().unwrap())
.map(|v| v.to_string()),
}),
Err(err) => Err(err),
}
false => Err(JsError::new(Status::Unknown, "Feed exceeded maximum size"))
}
}, },
Err(err) => Err(JsError::new(Status::Unknown, err)), Err(err) => Err(JsError::new(Status::Unknown, err)),
}, },

View File

@ -39,12 +39,12 @@ class MockMessageQueue extends EventEmitter implements MessageQueue {
} }
} }
async function constructFeedReader(feedResponse: () => {headers: Record<string,string>, data: string}, extraConfig?: Partial<BridgeConfigFeedsYAML>) { async function constructFeedReader(feedResponse: () => {headers?: Record<string,string>, data: string}, extraConfig?: Partial<BridgeConfigFeedsYAML>) {
const httpServer = await new Promise<Server>(resolve => { const httpServer = await new Promise<Server>(resolve => {
const srv = createServer((_req, res) => { const srv = createServer((_req, res) => {
const { headers, data } = feedResponse(); const { headers, data } = feedResponse();
Object.entries(headers).forEach(([key,value]) => { Object.entries(headers ?? {}).forEach(([key,value]) => {
res.setHeader(key, value); res.setHeader(key, value);
}); });
res.writeHead(200); res.writeHead(200);
@ -300,21 +300,44 @@ describe("FeedReader", () => {
}); });
it("should fail to handle a feed which exceed the maximum size.", async () => { it("should fail to handle a feed which exceed the maximum size.", async () => {
// Create some data of the right length
const data = `
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>RSS Title</title>
<description>This is an example of an RSS feed</description>
${Array.from({length: 8000}).map((_, i) => `<item>
<title>Example entry</title>
<guid isPermaLink="true">http://www.example.com/blog/post/${i}</guid>
</item>`).join('')}
</channel>
</rss>`;
const { feedReader, feedUrl } = await constructFeedReader(() => ({ const { feedReader, feedUrl } = await constructFeedReader(() => ({
headers: { data, headers: { 'Content-Length': data.length.toString()}
'Content-Length': Math.pow(1024, 2).toString(), }), {
}, data: ` maximumFeedSizeMB: 1
<?xml version="1.0" encoding="UTF-8" ?> });
<rss version="2.0"> await feedReader.pollFeed(feedUrl);
<channel> expect(feedReader["feedsFailingParsing"]).to.contain(feedUrl);
<title>RSS Title</title> });
<description>This is an example of an RSS feed</description>
<item> it("should fail to handle a feed which exceed the maximum size which does NOT send a Content-Length.", async () => {
<title>Example entry</title> // Create some data of the right length
<guid isPermaLink="true">http://www.example.com/blog/post/1</guid> const data = `
</item> <?xml version="1.0" encoding="UTF-8" ?>
</channel> <rss version="2.0">
</rss>` <channel>
<title>RSS Title</title>
<description>This is an example of an RSS feed</description>
${Array.from({length: 8000}).map((_, i) => `<item>
<title>Example entry</title>
<guid isPermaLink="true">http://www.example.com/blog/post/${i}</guid>
</item>`).join('')}
</channel>
</rss>`;
const { feedReader, feedUrl } = await constructFeedReader(() => ({
data
}), { }), {
maximumFeedSizeMB: 1 maximumFeedSizeMB: 1
}); });