@@ -8,6 +8,8 @@ import nock from 'nock';
88import sinon from 'sinon' ;
99import sinonChai from 'sinon-chai' ;
1010
11+ import { InaccessibleContentError } from './errors.js' ;
12+ import { FetchDocumentError } from './fetcher/index.js' ;
1113import Git from './recorder/repositories/git/git.js' ;
1214
1315import Archivist , { EVENTS } from './index.js' ;
@@ -245,6 +247,100 @@ describe('Archivist', function () {
245247 } ) ;
246248 } ) ;
247249
250+ describe ( '#handleTrackingError' , ( ) => {
251+ let errorSpy ;
252+ let warnSpy ;
253+ let inaccessibleContentSpy ;
254+ let pushSpy ;
255+ let terms ;
256+ let app ;
257+ const retryableError = new FetchDocumentError ( FetchDocumentError . LIKELY_TRANSIENT_ERRORS [ 0 ] ) ;
258+
259+ before ( async ( ) => {
260+ app = new Archivist ( {
261+ recorderConfig : config . get ( '@opentermsarchive/engine.recorder' ) ,
262+ fetcherConfig : config . get ( '@opentermsarchive/engine.fetcher' ) ,
263+ } ) ;
264+ await app . initialize ( ) ;
265+ } ) ;
266+
267+ beforeEach ( ( ) => {
268+ errorSpy = sinon . spy ( ) ;
269+ warnSpy = sinon . spy ( ) ;
270+ inaccessibleContentSpy = sinon . spy ( ) ;
271+ pushSpy = sinon . spy ( app . trackingQueue , 'push' ) ;
272+ app . on ( 'error' , errorSpy ) ;
273+ app . on ( 'warn' , warnSpy ) ;
274+ app . on ( 'inaccessibleContent' , inaccessibleContentSpy ) ;
275+
276+ terms = {
277+ service : { id : 'test-service' } ,
278+ type : 'test-type' ,
279+ sourceDocuments : [
280+ { location : 'https://example.com/doc1' } ,
281+ { location : 'https://example.com/doc2' } ,
282+ ] ,
283+ } ;
284+ } ) ;
285+
286+ afterEach ( ( ) => {
287+ errorSpy . resetHistory ( ) ;
288+ warnSpy . resetHistory ( ) ;
289+ inaccessibleContentSpy . resetHistory ( ) ;
290+ pushSpy . restore ( ) ;
291+ } ) ;
292+
293+ context ( 'with an InaccessibleContentError' , ( ) => {
294+ context ( 'when error may be transient' , ( ) => {
295+ beforeEach ( ( ) => {
296+ const error = new InaccessibleContentError ( [ retryableError ] ) ;
297+
298+ app . handleTrackingError ( error , { terms } ) ;
299+ } ) ;
300+
301+ it ( 'does not emit an error event' , ( ) => {
302+ expect ( errorSpy ) . to . not . have . been . called ;
303+ } ) ;
304+
305+ it ( 'does not emit an inaccessibleContent event' , ( ) => {
306+ expect ( inaccessibleContentSpy ) . to . not . have . been . called ;
307+ } ) ;
308+
309+ it ( 'emits a warning' , ( ) => {
310+ expect ( warnSpy ) . to . have . been . called ;
311+ } ) ;
312+
313+ it ( 'pushes terms to tracking queue for retry' , ( ) => {
314+ expect ( pushSpy ) . to . have . been . calledWith ( { terms, isRetry : true } ) ;
315+ } ) ;
316+ } ) ;
317+
318+ context ( 'when error comes from a retry' , ( ) => {
319+ beforeEach ( ( ) => {
320+ const error = new InaccessibleContentError ( [ retryableError ] ) ;
321+
322+ app . handleTrackingError ( error , { terms, isRetry : true } ) ;
323+ } ) ;
324+
325+ it ( 'does not emit an error event' , ( ) => {
326+ expect ( errorSpy ) . to . not . have . been . called ;
327+ } ) ;
328+
329+ it ( 'does not emit a warning' , ( ) => {
330+ expect ( warnSpy ) . to . not . have . been . called ;
331+ } ) ;
332+
333+ it ( 'emits an inaccessibleContent event with error and terms' , ( ) => {
334+ expect ( inaccessibleContentSpy ) . to . have . been . called ;
335+ } ) ;
336+
337+ it ( 'does not push terms to tracking queue for retry' , ( ) => {
338+ expect ( pushSpy ) . to . not . have . been . called ;
339+ } ) ;
340+ } ) ;
341+ } ) ;
342+ } ) ;
343+
248344 describe ( 'Plugin system' , ( ) => {
249345 const plugin = { } ;
250346
0 commit comments