Skip to content

Commit

Permalink
Attachment after update
Browse files Browse the repository at this point in the history
  • Loading branch information
minottic authored Apr 18, 2024
1 parent fdfd91e commit dc07b3a
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 10 deletions.
63 changes: 60 additions & 3 deletions sci-log-db/src/__tests__/unit/service.export-snippet.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,13 @@ describe('Export service unit', function (this: Suite) {
const exportFile = await exportService['exportToPdf'](
paragraphs,
{exportFile: 'dir/file.pdf', exportDir: 'dir'},
{authorization: 'Bearer XXXX'},
'aTitle',
);
expect(addTitle.callCount).to.be.eql(1);
expect(exportService.authorizationHeader).to.be.eql({
authorization: 'Bearer XXXX',
});
expect(htmlToPDF.callCount).to.be.eql(o);
expect(exportFile).to.be.eql('dir/file.pdf');
});
Expand Down Expand Up @@ -341,6 +345,26 @@ describe('Export service unit', function (this: Suite) {
[['someFile_>_.pdf', 'accessHash2']],
],
},
{
input: [
{files: []},
'<div class="fileLink" href="https://some/download/111fd07c4f1f010a51e32b36">someFile.pdf</div>',
],
expected: [
'<filelink>attachments/someFile.pdf</filelink>',
[['someFile.pdf', '111fd07c4f1f010a51e32b36']],
],
},
{
input: [
{files: []},
'<div class="fileLink" href="https://some/download/1">someFile.pdf</div>',
],
expected: [
'<div class="fileLink" href="https://some/download/1">someFile.pdf</div>',
[],
],
},
].forEach((t, i) => {
it(`attachment ${i}`, async () => {
const element = textContentToHTML({textcontent: t.input[1]} as Paragraph);
Expand All @@ -357,12 +381,15 @@ describe('Export service unit', function (this: Suite) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.resolves({arrayBuffer: async () => '' as any} as Response);
sandbox.stub(Buffer, 'from');
exportService.authorizationHeader = {authorization: 'Bearer XXXX'};
const writeFileSpy = sandbox.stub(fspromise, 'writeFile');
await exportService['downloadAttachment']('someDir', ['a', 'b']);
expect(writeFileSpy.calledWith('someDir/a', match.any)).to.be.eql(true);
expect(responseSpy.calledWith('http://localhost:3000/images/b')).to.be.eql(
true,
);
expect(
responseSpy.calledWith('http://localhost:3000/images/b', {
headers: {authorization: 'Bearer XXXX'},
}),
).to.be.eql(true);
});

[
Expand Down Expand Up @@ -394,4 +421,34 @@ describe('Export service unit', function (this: Suite) {
).to.eql(t.expected[2]);
});
});

[
{input: [null], expected: undefined},
{input: ['some'], expected: undefined},
{input: ['https://abc'], expected: undefined},
{input: ['http://abc'], expected: undefined},
{input: ['http://abc/download'], expected: undefined},
{input: ['http://abc/download/123'], expected: undefined},
{
input: ['http://abc/download/111fd07c4f1f010a51e32b36'],
expected: '111fd07c4f1f010a51e32b36',
},
{input: ['file:somefile', []], expected: undefined},
{
input: [
'file:somefile',
[{fileHash: 'somefile', accessHash: 'accessHash'}],
],
expected: 'accessHash',
},
].forEach((t, i) => {
it(`attachmentDownloadUrl ${i}`, async () => {
expect(
exportService['attachmentDownloadUrl'](
t.input[0] as string | null,
t.input[1] as {fileHash?: string; accessHash?: string}[] | undefined,
),
).to.eql(t.expected);
});
});
});
1 change: 1 addition & 0 deletions sci-log-db/src/mixins/basesnippet.repository-mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ function ExportRepositoryMixin<
const outFile = await exportService.exportToPdf(
snippets as unknown as Paragraph[],
{exportFile, exportDir},
_.pick(response?.req?.headers, 'authorization'),
parentName,
);
response.download(outFile, (err, path = exportDir) => {
Expand Down
39 changes: 32 additions & 7 deletions sci-log-db/src/services/export-snippets.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class ExportService {
subsnippetCounter: number;
attachments: string[][] = [];
attachmentsFolder = 'attachments';
authorizationHeader: {authorization?: string};

constructor(
@inject(RestBindings.SERVER)
Expand Down Expand Up @@ -228,20 +229,40 @@ export class ExportService {
};

private attachment = (snippet: Paragraph, element: Element) => {
snippet.files?.map(fileSnippet => {
const fileLinkElement = element.querySelector(
`.fileLink[href='file:${fileSnippet.fileHash}']`,
);
if (!fileLinkElement) return;
element.querySelectorAll('.fileLink').forEach(fileLinkElement => {
const href = fileLinkElement.getAttribute('href');
const downloadUrl = this.attachmentDownloadUrl(href, snippet.files);
if (!downloadUrl) return;
const attachment = fileLinkElement.textContent ?? '';
const attachmentElement = this.document.createElement('fileLink');
attachmentElement.innerHTML = `${this.attachmentsFolder}/${fileLinkElement.innerHTML}`;
fileLinkElement.replaceWith(attachmentElement);
this.attachments.push([attachment, fileSnippet.accessHash as string]);
this.attachments.push([attachment, downloadUrl]);
});
return element;
};

private attachmentDownloadUrl(
href: string | null,
files: {fileHash?: string; accessHash?: string}[] | undefined,
) {
let accessHash: string | undefined;
if (href?.startsWith('https://') || href?.startsWith('http://')) {
const objectId = require('mongodb').ObjectId;
const hrefParts = href.split('/');
const fileId = hrefParts.pop();
if (objectId.isValid(fileId) && hrefParts.pop() === 'download')
return fileId;
return;
} else if (
files?.some(
f => `file:${f.fileHash}` === href && (accessHash = f.accessHash),
)
)
return accessHash;
return;
}

private countSnippets(linkType?: LinkType) {
let counter: number | string = '';
if (linkType === 'paragraph') {
Expand All @@ -264,8 +285,10 @@ export class ExportService {
async exportToPdf(
snippets: Paragraph[],
exportPath: {exportFile: string; exportDir: string},
authorizationHeader: {authorization?: string},
title?: string,
) {
this.authorizationHeader = authorizationHeader;
const browser = await puppeteerLaunc({
executablePath: process.env.CHROME_BIN,
args: ['--no-sandbox'],
Expand Down Expand Up @@ -320,7 +343,9 @@ export class ExportService {
attachmentDir: string,
attachment: string[],
) {
const response = await fetch(`${this.server.url}/images/${attachment[1]}`);
const response = await fetch(`${this.server.url}/images/${attachment[1]}`, {
headers: this.authorizationHeader,
});
const buffer = Buffer.from(await response.arrayBuffer());
const destinationFile = `${attachmentDir}/${attachment[0]}`;
await writeFile(destinationFile, buffer);
Expand Down

0 comments on commit dc07b3a

Please sign in to comment.