Files
memind/server/portal-published-page-delivery.test.mjs

218 lines
4.6 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
createPortalPublishedPageDelivery,
} from './portal-published-page-delivery.mjs';
function createResponse() {
return {
statusCode: 200,
body: undefined,
headers: {},
status(code) {
this.statusCode = code;
return this;
},
type(value) {
this.headers['Content-Type'] = value;
return this;
},
set(name, value) {
this.headers[name] = value;
return this;
},
send(body) {
this.body = body;
return this;
},
removeHeader(name) {
delete this.headers[name];
},
};
}
function createRequest(overrides = {}) {
return {
originalUrl:
'/u/alice/pages/demo?source=test',
url: '/u/alice/pages/demo',
query: {},
headers: {
host: 'portal.example',
},
protocol: 'https',
get(name) {
return name === 'user-agent'
? 'desktop browser'
: '';
},
...overrides,
};
}
function createResult(overrides = {}) {
return {
html: '<!doctype html><html><head><title>Demo Page</title></head><body><main>Demo</main></body></html>',
publication: {
accessMode: 'public',
},
pageSource: null,
...overrides,
};
}
test('wraps a normal full HTML publication in the share shell', async () => {
const sendPublishedPage =
createPortalPublishedPageDelivery({
async registerLongImageArtifact() {},
});
const response = createResponse();
await sendPublishedPage(
createRequest(),
response,
createResult(),
);
assert.equal(response.statusCode, 200);
assert.match(
response.body,
/class="publication-frame"/,
);
assert.match(
response.body,
/view=raw/,
);
assert.equal(
response.headers['Cache-Control'],
'public, max-age=60',
);
});
test('raw and password publications bypass the share shell', async () => {
const sendPublishedPage =
createPortalPublishedPageDelivery({
async registerLongImageArtifact() {},
});
const rawResponse = createResponse();
await sendPublishedPage(
createRequest(),
rawResponse,
createResult(),
{ raw: true },
);
assert.doesNotMatch(
rawResponse.body,
/publication-frame/,
);
assert.match(rawResponse.body, /Demo/);
const passwordResponse = createResponse();
await sendPublishedPage(
createRequest(),
passwordResponse,
createResult({
publication: {
accessMode: 'password',
},
}),
);
assert.doesNotMatch(
passwordResponse.body,
/publication-frame/,
);
assert.equal(
passwordResponse.headers['Cache-Control'],
'private, no-store',
);
});
test('embed mode delivers embedded HTML and frame headers', async () => {
const sendPublishedPage =
createPortalPublishedPageDelivery({
async registerLongImageArtifact() {},
});
const response = createResponse();
await sendPublishedPage(
createRequest(),
response,
createResult(),
{ embed: true },
);
assert.doesNotMatch(
response.body,
/publication-frame/,
);
assert.equal(
response.headers['X-Frame-Options'],
undefined,
);
});
test('long-image download renders, registers, and returns PNG', async () => {
const calls = [];
const image = Buffer.from('png-image');
const sendPublishedPage =
createPortalPublishedPageDelivery({
async renderLongImage(options) {
calls.push(['render', options]);
return image;
},
async registerLongImageArtifact(
options,
) {
calls.push(['register', options]);
},
});
const response = createResponse();
await sendPublishedPage(
createRequest({
query: {
download: 'long-image',
},
}),
response,
createResult(),
);
assert.equal(response.body, image);
assert.equal(
response.headers['Content-Type'],
'image/png',
);
assert.equal(
response.headers['Cache-Control'],
'no-store',
);
assert.match(
calls[0][1].url,
/view=raw/,
);
assert.match(
calls[1][1].canonicalUrl,
/download=long-image/,
);
});
test('long-image failures preserve the public error response', async () => {
const sendPublishedPage =
createPortalPublishedPageDelivery({
async renderLongImage() {
throw new Error('renderer failed');
},
async registerLongImageArtifact() {},
});
const response = createResponse();
await sendPublishedPage(
createRequest({
query: {
download: 'long-image',
},
}),
response,
createResult(),
);
assert.equal(response.statusCode, 500);
assert.match(
response.body,
/renderer failed/,
);
});