Commit da7b94c9 authored by Robert Knight's avatar Robert Knight

Add `extra.{source, original_id}` fields to imported annotations

Record the fact that imported annotations were created via the client's import
mechanism, and the original ID of the annotation. This is currently stored in
the `extra` field. h supports setting arbitrary fields at the top level of
annotations, so we could have put the data there instead. However using the
`extra` field for custom fields is a convention already used by some API
clients, and is distinct from a standard/validated field if we add one later on.

Fixes https://github.com/hypothesis/client/issues/5738
parent 23dffed3
......@@ -7,13 +7,31 @@ import type { ToastMessengerService } from './toast-messenger';
/** Number of annotations to import concurrently. */
export const MAX_CONCURRENT_IMPORTS = 5;
/**
* Non-standard metadata fields added to imported annotations.
*
* These are added for analytics / reporting purposes. If we decide to make
* other uses of it, we should migrate these to a proper annotation metadata
* field.
*/
type ImportExtra = {
extra: {
/** Indicator for where the annotation came from. */
source: 'import';
/** Original ID of the annotation that was imported. */
original_id?: string;
};
};
/**
* The subset of annotation fields which are preserved during an import.
*/
type ImportData = Pick<
APIAnnotationData,
'document' | 'tags' | 'text' | 'target' | 'uri'
>;
> &
ImportExtra;
/**
* Return a copy of `ann` that contains only fields which can be preserved by
......@@ -26,6 +44,10 @@ function getImportData(ann: APIAnnotationData): ImportData {
text: ann.text,
uri: ann.uri,
document: ann.document,
extra: {
source: 'import',
original_id: ann.id,
},
};
}
......
......@@ -43,6 +43,7 @@ describe('ImportAnnotationsService', () => {
function generateAnnotation(fields = {}) {
++counter;
return {
id: `id-${counter}`,
uri: 'https://example.com',
target: [
{
......@@ -56,6 +57,21 @@ describe('ImportAnnotationsService', () => {
};
}
/** Return the expected imported annotation for a given annotation. */
function importedAnnotation(ann) {
return {
document: ann.document,
tags: ann.tags,
target: ann.target,
text: ann.text,
uri: ann.uri,
extra: {
source: 'import',
original_id: ann.id,
},
};
}
describe('#import', () => {
it('increments count of pending imports', async () => {
const svc = createService();
......@@ -80,7 +96,7 @@ describe('ImportAnnotationsService', () => {
assert.calledWith(fakeAnnotationsService.save, {
$tag: 'dummy',
...ann,
...importedAnnotation(ann),
});
});
......@@ -98,7 +114,7 @@ describe('ImportAnnotationsService', () => {
for (const ann of anns) {
assert.calledWith(fakeAnnotationsService.save, {
$tag: 'dummy',
...ann,
...importedAnnotation(ann),
});
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment