Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
5c969487
Commit
5c969487
authored
Jan 16, 2024
by
Alejandro Celaya
Committed by
Alejandro Celaya
Jan 16, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace all file-downloading function with one which expects the type
parent
4ce317f5
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
39 additions
and
105 deletions
+39
-105
download-file.ts
src/shared/download-file.ts
+6
-22
download-file-test.js
src/shared/test/download-file-test.js
+8
-38
ExportAnnotations.tsx
src/sidebar/components/ShareDialog/ExportAnnotations.tsx
+13
-24
ExportAnnotations-test.js
...bar/components/ShareDialog/test/ExportAnnotations-test.js
+12
-21
No files found.
src/shared/download-file.ts
View file @
5c969487
function
downloadFile
(
export
function
downloadFile
(
content
:
string
,
type
:
string
,
filename
:
string
,
document
:
Document
,
/* istanbul ignore next - test seam */
document_
=
document
,
):
void
{
const
blob
=
new
Blob
([
content
],
{
type
});
const
url
=
URL
.
createObjectURL
(
blob
);
const
link
=
document
.
createElement
(
'a'
);
const
link
=
document
_
.
createElement
(
'a'
);
link
.
setAttribute
(
'href'
,
url
);
link
.
setAttribute
(
'download'
,
filename
);
link
.
style
.
visibility
=
'hidden'
;
document
.
body
.
appendChild
(
link
);
document
_
.
body
.
appendChild
(
link
);
link
.
click
();
document
.
body
.
removeChild
(
link
);
document
_
.
body
.
removeChild
(
link
);
URL
.
revokeObjectURL
(
url
);
}
function
buildTextFileDownloader
(
type
:
string
)
{
return
(
text
:
string
,
filename
:
string
,
/* istanbul ignore next - test seam */
_document
=
document
,
)
=>
downloadFile
(
text
,
type
,
filename
,
_document
);
}
export
const
downloadJSONFile
=
buildTextFileDownloader
(
'application/json'
);
export
const
downloadTextFile
=
buildTextFileDownloader
(
'text/plain'
);
export
const
downloadCSVFile
=
buildTextFileDownloader
(
'text/csv'
);
export
const
downloadHTMLFile
=
buildTextFileDownloader
(
'text/html'
);
src/shared/test/download-file-test.js
View file @
5c969487
import
{
downloadCSVFile
,
downloadHTMLFile
,
downloadJSONFile
,
downloadTextFile
,
}
from
'../download-file'
;
import
{
downloadFile
}
from
'../download-file'
;
describe
(
'download-file'
,
()
=>
{
let
fakeLink
;
...
...
@@ -47,39 +42,14 @@ describe('download-file', () => {
assert
.
equal
(
'hidden'
,
fakeLink
.
style
.
visibility
);
}
it
(
'downloadJSONFile generates JSON file with provided data'
,
()
=>
{
const
data
=
JSON
.
stringify
({
foo
:
[
'bar'
,
'baz'
]
},
null
,
2
);
const
filename
=
'my-file.json'
;
downloadJSONFile
(
data
,
filename
,
fakeDocument
);
assertDownloadHappened
(
filename
,
data
,
'application/json'
);
});
[
'application/json'
,
'text/plain'
,
'text/csv'
,
'text/html'
].
forEach
(
type
=>
{
it
(
'downloadTextFile generates text file with provided data'
,
()
=>
{
const
data
=
'The content of the file'
;
const
filename
=
'my-file.txt'
;
downloadTextFile
(
data
,
filename
,
fakeDocument
);
downloadFile
(
data
,
type
,
filename
,
fakeDocument
);
assertDownloadHappened
(
filename
,
data
,
'text/plain'
);
assertDownloadHappened
(
filename
,
data
,
type
);
});
it
(
'downloadCSVFile generates csv file with provided data'
,
()
=>
{
const
data
=
'foo,bar,baz'
;
const
filename
=
'my-file.csv'
;
downloadCSVFile
(
data
,
filename
,
fakeDocument
);
assertDownloadHappened
(
filename
,
data
,
'text/csv'
);
});
it
(
'downloadHTMLFile generates HTML file with provided data'
,
()
=>
{
const
data
=
'<p>Hello</p>'
;
const
filename
=
'my-file.html'
;
downloadHTMLFile
(
data
,
filename
,
fakeDocument
);
assertDownloadHappened
(
filename
,
data
,
'text/html'
);
});
});
src/sidebar/components/ShareDialog/ExportAnnotations.tsx
View file @
5c969487
...
...
@@ -8,12 +8,7 @@ import {
}
from
'@hypothesis/frontend-shared'
;
import
{
useCallback
,
useId
,
useMemo
,
useState
}
from
'preact/hooks'
;
import
{
downloadCSVFile
,
downloadHTMLFile
,
downloadJSONFile
,
downloadTextFile
,
}
from
'../../../shared/download-file'
;
import
{
downloadFile
}
from
'../../../shared/download-file'
;
import
type
{
APIAnnotationData
}
from
'../../../types/api'
;
import
{
annotationDisplayName
}
from
'../../helpers/annotation-user'
;
import
type
{
UserAnnotations
}
from
'../../helpers/annotations-by-user'
;
...
...
@@ -74,6 +69,16 @@ const exportFormats: ExportFormat[] = [
},
];
function
formatToMimeType
(
format
:
ExportFormat
[
'value'
]):
string
{
const
typeForFormat
:
Record
<
ExportFormat
[
'value'
],
string
>
=
{
json
:
'application/json'
,
txt
:
'text/plain'
,
csv
:
'text/csv'
,
html
:
'text/html'
,
};
return
typeForFormat
[
format
];
}
/**
* Render content for "export" tab panel: allow user to export annotations
* with a specified filename.
...
...
@@ -200,25 +205,9 @@ function ExportAnnotations({
const
format
=
exportFormat
.
value
;
const
filename
=
`
${
customFilename
??
defaultFilename
}.
$
{
format
}
`;
const exportData = buildExportContent(format);
const mimeType = formatToMimeType(format);
switch (format) {
case 'json': {
downloadJSONFile(exportData, filename);
break;
}
case 'txt': {
downloadTextFile(exportData, filename);
break;
}
case 'csv': {
downloadCSVFile(exportData, filename);
break;
}
case 'html': {
downloadHTMLFile(exportData, filename);
break;
}
}
downloadFile(exportData, mimeType, filename);
} catch (e) {
toastMessenger.error('Exporting annotations failed');
}
...
...
src/sidebar/components/ShareDialog/test/ExportAnnotations-test.js
View file @
5c969487
...
...
@@ -14,10 +14,7 @@ describe('ExportAnnotations', () => {
let
fakeStore
;
let
fakeAnnotationsExporter
;
let
fakeToastMessenger
;
let
fakeDownloadJSONFile
;
let
fakeDownloadTextFile
;
let
fakeDownloadCSVFile
;
let
fakeDownloadHTMLFile
;
let
fakeDownloadFile
;
let
fakeSuggestedFilename
;
let
fakeCopyPlainText
;
let
fakeCopyHTML
;
...
...
@@ -48,10 +45,7 @@ describe('ExportAnnotations', () => {
error
:
sinon
.
stub
(),
success
:
sinon
.
stub
(),
};
fakeDownloadJSONFile
=
sinon
.
stub
();
fakeDownloadTextFile
=
sinon
.
stub
();
fakeDownloadCSVFile
=
sinon
.
stub
();
fakeDownloadHTMLFile
=
sinon
.
stub
();
fakeDownloadFile
=
sinon
.
stub
();
fakeStore
=
{
defaultAuthority
:
sinon
.
stub
().
returns
(
'example.com'
),
isFeatureEnabled
:
sinon
.
stub
().
returns
(
true
),
...
...
@@ -74,10 +68,7 @@ describe('ExportAnnotations', () => {
$imports
.
$mock
({
'../../../shared/download-file'
:
{
downloadJSONFile
:
fakeDownloadJSONFile
,
downloadTextFile
:
fakeDownloadTextFile
,
downloadCSVFile
:
fakeDownloadCSVFile
,
downloadHTMLFile
:
fakeDownloadHTMLFile
,
downloadFile
:
fakeDownloadFile
,
},
'../../helpers/export-annotations'
:
{
suggestedFilename
:
fakeSuggestedFilename
,
...
...
@@ -408,21 +399,21 @@ describe('ExportAnnotations', () => {
[
{
format
:
'json'
,
getExpectedInvokedDownloader
:
()
=>
fakeDownloadJSONFile
,
expectedMimeType
:
'application/json'
,
},
{
format
:
'txt'
,
getExpectedInvokedDownloader
:
()
=>
fakeDownloadTextFile
,
expectedMimeType
:
'text/plain'
,
},
{
format
:
'csv'
,
getExpectedInvokedDownloader
:
()
=>
fakeDownloadCSVFile
,
expectedMimeType
:
'text/csv'
,
},
{
format
:
'html'
,
getExpectedInvokedDownloader
:
()
=>
fakeDownloadHTMLFile
,
expectedMimeType
:
'text/html'
,
},
].
forEach
(({
format
,
getExpectedInvokedDownloader
})
=>
{
].
forEach
(({
format
,
expectedMimeType
})
=>
{
it
(
'downloads a file using user-entered filename appended with proper extension'
,
async
()
=>
{
const
wrapper
=
createComponent
();
const
filenameInput
=
wrapper
.
find
(
...
...
@@ -436,11 +427,11 @@ describe('ExportAnnotations', () => {
submitExportForm
(
wrapper
);
const
invokedDownloader
=
getExpectedInvokedDownloader
();
assert
.
calledOnce
(
invokedDownloader
);
assert
.
calledOnce
(
fakeDownloadFile
);
assert
.
calledWith
(
invokedDownloader
,
fakeDownloadFile
,
sinon
.
match
.
any
,
expectedMimeType
,
`my-filename.
${
format
}
`
,
);
});
...
...
@@ -456,7 +447,7 @@ describe('ExportAnnotations', () => {
submitExportForm
(
wrapper
);
assert
.
notCalled
(
fakeDownload
JSON
File
);
assert
.
notCalled
(
fakeDownloadFile
);
assert
.
calledOnce
(
fakeAnnotationsExporter
.
buildJSONExportContent
);
assert
.
calledWith
(
fakeToastMessenger
.
error
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment