@fluidframework/odsp-driver 2.0.0-dev-rc.2.0.0.246488 → 2.0.0-dev-rc.3.0.0.250606
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/WriteBufferUtils.d.ts.map +1 -1
- package/dist/WriteBufferUtils.js.map +1 -1
- package/dist/compactSnapshotParser.d.ts +1 -1
- package/dist/compactSnapshotParser.d.ts.map +1 -1
- package/dist/compactSnapshotParser.js +1 -1
- package/dist/compactSnapshotParser.js.map +1 -1
- package/dist/compactSnapshotWriter.d.ts.map +1 -1
- package/dist/compactSnapshotWriter.js +1 -1
- package/dist/compactSnapshotWriter.js.map +1 -1
- package/dist/contracts.d.ts +2 -2
- package/dist/contracts.d.ts.map +1 -1
- package/dist/contracts.js.map +1 -1
- package/dist/createFile.d.ts +2 -2
- package/dist/createFile.d.ts.map +1 -1
- package/dist/createFile.js +7 -7
- package/dist/createFile.js.map +1 -1
- package/dist/createNewContainerOnExistingFile.d.ts +2 -2
- package/dist/createNewContainerOnExistingFile.d.ts.map +1 -1
- package/dist/createNewContainerOnExistingFile.js +4 -4
- package/dist/createNewContainerOnExistingFile.js.map +1 -1
- package/dist/createNewUtils.d.ts +2 -2
- package/dist/createNewUtils.d.ts.map +1 -1
- package/dist/createNewUtils.js +4 -4
- package/dist/createNewUtils.js.map +1 -1
- package/dist/epochTracker.d.ts +3 -3
- package/dist/epochTracker.d.ts.map +1 -1
- package/dist/epochTracker.js +4 -4
- package/dist/epochTracker.js.map +1 -1
- package/dist/fetch.js.map +1 -1
- package/dist/fetchSnapshot.d.ts +2 -2
- package/dist/fetchSnapshot.d.ts.map +1 -1
- package/dist/fetchSnapshot.js +5 -5
- package/dist/fetchSnapshot.js.map +1 -1
- package/dist/getFileLink.d.ts +1 -1
- package/dist/getFileLink.d.ts.map +1 -1
- package/dist/getFileLink.js +1 -1
- package/dist/getFileLink.js.map +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.js +1 -1
- package/dist/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentService.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.js +1 -1
- package/dist/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js +2 -2
- package/dist/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/dist/odspCache.d.ts +1 -1
- package/dist/odspCache.d.ts.map +1 -1
- package/dist/odspCache.js.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.d.ts +4 -4
- package/dist/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/dist/odspDelayLoadedDeltaStream.js +11 -6
- package/dist/odspDelayLoadedDeltaStream.js.map +1 -1
- package/dist/odspDeltaStorageService.d.ts +3 -3
- package/dist/odspDeltaStorageService.d.ts.map +1 -1
- package/dist/odspDeltaStorageService.js +3 -3
- package/dist/odspDeltaStorageService.js.map +1 -1
- package/dist/odspDocumentDeltaConnection.d.ts +5 -4
- package/dist/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/dist/odspDocumentDeltaConnection.js +3 -5
- package/dist/odspDocumentDeltaConnection.js.map +1 -1
- package/dist/odspDocumentService.d.ts +4 -4
- package/dist/odspDocumentService.d.ts.map +1 -1
- package/dist/odspDocumentService.js +2 -2
- package/dist/odspDocumentService.js.map +1 -1
- package/dist/odspDocumentServiceFactory.d.ts +1 -1
- package/dist/odspDocumentServiceFactory.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactory.js +1 -1
- package/dist/odspDocumentServiceFactory.js.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.d.ts +2 -2
- package/dist/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryCore.js +2 -2
- package/dist/odspDocumentServiceFactoryCore.js.map +1 -1
- package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts +1 -1
- package/dist/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +1 -1
- package/dist/odspDocumentServiceFactoryWithCodeSplit.js.map +1 -1
- package/dist/odspDocumentStorageManager.d.ts +4 -4
- package/dist/odspDocumentStorageManager.d.ts.map +1 -1
- package/dist/odspDocumentStorageManager.js +3 -3
- package/dist/odspDocumentStorageManager.js.map +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts +1 -1
- package/dist/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/dist/odspDocumentStorageServiceBase.js.map +1 -1
- package/dist/odspDriverUrlResolver.d.ts.map +1 -1
- package/dist/odspDriverUrlResolver.js +3 -3
- package/dist/odspDriverUrlResolver.js.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts +1 -1
- package/dist/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/dist/odspDriverUrlResolverForShareLink.js +2 -2
- package/dist/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/dist/odspError.d.ts.map +1 -1
- package/dist/odspError.js +1 -1
- package/dist/odspError.js.map +1 -1
- package/dist/odspFluidFileLink.d.ts.map +1 -1
- package/dist/odspFluidFileLink.js.map +1 -1
- package/dist/odspPublicUtils.js.map +1 -1
- package/dist/odspSnapshotParser.d.ts.map +1 -1
- package/dist/odspSnapshotParser.js.map +1 -1
- package/dist/odspSummaryUploadManager.d.ts +1 -1
- package/dist/odspSummaryUploadManager.d.ts.map +1 -1
- package/dist/odspSummaryUploadManager.js +1 -1
- package/dist/odspSummaryUploadManager.js.map +1 -1
- package/dist/odspUtils.d.ts +2 -2
- package/dist/odspUtils.d.ts.map +1 -1
- package/dist/odspUtils.js +2 -2
- package/dist/odspUtils.js.map +1 -1
- package/dist/opsCaching.d.ts.map +1 -1
- package/dist/opsCaching.js.map +1 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/prefetchLatestSnapshot.d.ts.map +1 -1
- package/dist/prefetchLatestSnapshot.js +1 -1
- package/dist/prefetchLatestSnapshot.js.map +1 -1
- package/dist/retryErrorsStorageAdapter.d.ts +2 -2
- package/dist/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/dist/retryErrorsStorageAdapter.js.map +1 -1
- package/dist/retryUtils.d.ts.map +1 -1
- package/dist/retryUtils.js.map +1 -1
- package/dist/vroom.d.ts +2 -2
- package/dist/vroom.d.ts.map +1 -1
- package/dist/vroom.js +2 -2
- package/dist/vroom.js.map +1 -1
- package/dist/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/dist/zipItDataRepresentationUtils.js +1 -1
- package/dist/zipItDataRepresentationUtils.js.map +1 -1
- package/lib/WriteBufferUtils.d.ts.map +1 -1
- package/lib/WriteBufferUtils.js +1 -1
- package/lib/WriteBufferUtils.js.map +1 -1
- package/lib/compactSnapshotParser.d.ts +1 -1
- package/lib/compactSnapshotParser.d.ts.map +1 -1
- package/lib/compactSnapshotParser.js +1 -1
- package/lib/compactSnapshotParser.js.map +1 -1
- package/lib/compactSnapshotWriter.d.ts.map +1 -1
- package/lib/compactSnapshotWriter.js +2 -2
- package/lib/compactSnapshotWriter.js.map +1 -1
- package/lib/contracts.d.ts +2 -2
- package/lib/contracts.d.ts.map +1 -1
- package/lib/contracts.js.map +1 -1
- package/lib/createFile.d.ts +2 -2
- package/lib/createFile.d.ts.map +1 -1
- package/lib/createFile.js +7 -7
- package/lib/createFile.js.map +1 -1
- package/lib/createNewContainerOnExistingFile.d.ts +2 -2
- package/lib/createNewContainerOnExistingFile.d.ts.map +1 -1
- package/lib/createNewContainerOnExistingFile.js +4 -4
- package/lib/createNewContainerOnExistingFile.js.map +1 -1
- package/lib/createNewUtils.d.ts +2 -2
- package/lib/createNewUtils.d.ts.map +1 -1
- package/lib/createNewUtils.js +5 -5
- package/lib/createNewUtils.js.map +1 -1
- package/lib/epochTracker.d.ts +3 -3
- package/lib/epochTracker.d.ts.map +1 -1
- package/lib/epochTracker.js +6 -6
- package/lib/epochTracker.js.map +1 -1
- package/lib/fetch.js.map +1 -1
- package/lib/fetchSnapshot.d.ts +2 -2
- package/lib/fetchSnapshot.d.ts.map +1 -1
- package/lib/fetchSnapshot.js +6 -6
- package/lib/fetchSnapshot.js.map +1 -1
- package/lib/getFileLink.d.ts +1 -1
- package/lib/getFileLink.d.ts.map +1 -1
- package/lib/getFileLink.js +1 -1
- package/lib/getFileLink.js.map +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.d.ts +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.js +1 -1
- package/lib/localOdspDriver/localOdspDeltaStorageService.js.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentService.d.ts +1 -1
- package/lib/localOdspDriver/localOdspDocumentService.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentService.js.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.js +1 -1
- package/lib/localOdspDriver/localOdspDocumentServiceFactory.js.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.d.ts.map +1 -1
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js +2 -2
- package/lib/localOdspDriver/localOdspDocumentStorageManager.js.map +1 -1
- package/lib/odspCache.d.ts +1 -1
- package/lib/odspCache.d.ts.map +1 -1
- package/lib/odspCache.js.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.d.ts +4 -4
- package/lib/odspDelayLoadedDeltaStream.d.ts.map +1 -1
- package/lib/odspDelayLoadedDeltaStream.js +11 -6
- package/lib/odspDelayLoadedDeltaStream.js.map +1 -1
- package/lib/odspDeltaStorageService.d.ts +3 -3
- package/lib/odspDeltaStorageService.d.ts.map +1 -1
- package/lib/odspDeltaStorageService.js +3 -3
- package/lib/odspDeltaStorageService.js.map +1 -1
- package/lib/odspDocumentDeltaConnection.d.ts +5 -4
- package/lib/odspDocumentDeltaConnection.d.ts.map +1 -1
- package/lib/odspDocumentDeltaConnection.js +4 -6
- package/lib/odspDocumentDeltaConnection.js.map +1 -1
- package/lib/odspDocumentService.d.ts +4 -4
- package/lib/odspDocumentService.d.ts.map +1 -1
- package/lib/odspDocumentService.js +2 -2
- package/lib/odspDocumentService.js.map +1 -1
- package/lib/odspDocumentServiceFactory.d.ts +1 -1
- package/lib/odspDocumentServiceFactory.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactory.js +1 -1
- package/lib/odspDocumentServiceFactory.js.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.d.ts +2 -2
- package/lib/odspDocumentServiceFactoryCore.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryCore.js +4 -4
- package/lib/odspDocumentServiceFactoryCore.js.map +1 -1
- package/lib/odspDocumentServiceFactoryWithCodeSplit.d.ts +1 -1
- package/lib/odspDocumentServiceFactoryWithCodeSplit.d.ts.map +1 -1
- package/lib/odspDocumentServiceFactoryWithCodeSplit.js.map +1 -1
- package/lib/odspDocumentStorageManager.d.ts +4 -4
- package/lib/odspDocumentStorageManager.d.ts.map +1 -1
- package/lib/odspDocumentStorageManager.js +4 -4
- package/lib/odspDocumentStorageManager.js.map +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts +1 -1
- package/lib/odspDocumentStorageServiceBase.d.ts.map +1 -1
- package/lib/odspDocumentStorageServiceBase.js.map +1 -1
- package/lib/odspDriverUrlResolver.d.ts.map +1 -1
- package/lib/odspDriverUrlResolver.js +3 -3
- package/lib/odspDriverUrlResolver.js.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts +1 -1
- package/lib/odspDriverUrlResolverForShareLink.d.ts.map +1 -1
- package/lib/odspDriverUrlResolverForShareLink.js +3 -3
- package/lib/odspDriverUrlResolverForShareLink.js.map +1 -1
- package/lib/odspError.d.ts.map +1 -1
- package/lib/odspError.js +1 -1
- package/lib/odspError.js.map +1 -1
- package/lib/odspFluidFileLink.d.ts.map +1 -1
- package/lib/odspFluidFileLink.js +1 -1
- package/lib/odspFluidFileLink.js.map +1 -1
- package/lib/odspPublicUtils.js +1 -1
- package/lib/odspPublicUtils.js.map +1 -1
- package/lib/odspSnapshotParser.d.ts.map +1 -1
- package/lib/odspSnapshotParser.js.map +1 -1
- package/lib/odspSummaryUploadManager.d.ts +1 -1
- package/lib/odspSummaryUploadManager.d.ts.map +1 -1
- package/lib/odspSummaryUploadManager.js +2 -2
- package/lib/odspSummaryUploadManager.js.map +1 -1
- package/lib/odspUtils.d.ts +2 -2
- package/lib/odspUtils.d.ts.map +1 -1
- package/lib/odspUtils.js +3 -3
- package/lib/odspUtils.js.map +1 -1
- package/lib/opsCaching.d.ts.map +1 -1
- package/lib/opsCaching.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/prefetchLatestSnapshot.d.ts.map +1 -1
- package/lib/prefetchLatestSnapshot.js +2 -2
- package/lib/prefetchLatestSnapshot.js.map +1 -1
- package/lib/retryErrorsStorageAdapter.d.ts +2 -2
- package/lib/retryErrorsStorageAdapter.d.ts.map +1 -1
- package/lib/retryErrorsStorageAdapter.js.map +1 -1
- package/lib/retryUtils.d.ts.map +1 -1
- package/lib/retryUtils.js.map +1 -1
- package/lib/test/createNewUtilsTests.spec.js +3 -3
- package/lib/test/createNewUtilsTests.spec.js.map +1 -1
- package/lib/test/deltaStorageService.spec.js +2 -2
- package/lib/test/deltaStorageService.spec.js.map +1 -1
- package/lib/test/epochTests.spec.js +2 -2
- package/lib/test/epochTests.spec.js.map +1 -1
- package/lib/test/epochTestsWithRedemption.spec.js +2 -2
- package/lib/test/epochTestsWithRedemption.spec.js.map +1 -1
- package/lib/test/fetchSnapshot.spec.js +8 -8
- package/lib/test/fetchSnapshot.spec.js.map +1 -1
- package/lib/test/getFileLink.spec.js +1 -1
- package/lib/test/getFileLink.spec.js.map +1 -1
- package/lib/test/getVersions.spec.js +6 -6
- package/lib/test/getVersions.spec.js.map +1 -1
- package/lib/test/joinSessionCacheTests.spec.js +117 -1
- package/lib/test/joinSessionCacheTests.spec.js.map +1 -1
- package/lib/test/joinSessionPeriodicCall.spec.js +3 -3
- package/lib/test/joinSessionPeriodicCall.spec.js.map +1 -1
- package/lib/test/localOdspDriver.spec.js +2 -2
- package/lib/test/localOdspDriver.spec.js.map +1 -1
- package/lib/test/mockFetch.js +1 -1
- package/lib/test/mockFetch.js.map +1 -1
- package/lib/test/odspCreateContainer.spec.js +7 -7
- package/lib/test/odspCreateContainer.spec.js.map +1 -1
- package/lib/test/odspDriverResolverTest.spec.js +2 -2
- package/lib/test/odspDriverResolverTest.spec.js.map +1 -1
- package/lib/test/odspDriverUrlResolverForShareLink.spec.js +4 -4
- package/lib/test/odspDriverUrlResolverForShareLink.spec.js.map +1 -1
- package/lib/test/odspError.spec.js +2 -2
- package/lib/test/odspError.spec.js.map +1 -1
- package/lib/test/opsCaching.spec.js +1 -1
- package/lib/test/opsCaching.spec.js.map +1 -1
- package/lib/test/prefetchSnapshotTests.spec.js +8 -8
- package/lib/test/prefetchSnapshotTests.spec.js.map +1 -1
- package/lib/test/snapshotFormatTests.spec.js.map +1 -1
- package/lib/test/socketTests/deltaConnectionUpdateTests.spec.js +4 -4
- package/lib/test/socketTests/deltaConnectionUpdateTests.spec.js.map +1 -1
- package/lib/test/socketTests/socketMock.js +6 -2
- package/lib/test/socketTests/socketMock.js.map +1 -1
- package/lib/test/socketTests/socketTests.spec.js +4 -4
- package/lib/test/socketTests/socketTests.spec.js.map +1 -1
- package/lib/test/tokenFetch.spec.js +1 -1
- package/lib/test/tokenFetch.spec.js.map +1 -1
- package/lib/test/zipItDataRepresentationTests.spec.js +1 -1
- package/lib/test/zipItDataRepresentationTests.spec.js.map +1 -1
- package/lib/vroom.d.ts +2 -2
- package/lib/vroom.d.ts.map +1 -1
- package/lib/vroom.js +2 -2
- package/lib/vroom.js.map +1 -1
- package/lib/zipItDataRepresentationUtils.d.ts.map +1 -1
- package/lib/zipItDataRepresentationUtils.js +1 -1
- package/lib/zipItDataRepresentationUtils.js.map +1 -1
- package/package.json +19 -16
- package/src/WriteBufferUtils.ts +2 -2
- package/src/compactSnapshotParser.ts +6 -6
- package/src/compactSnapshotWriter.ts +4 -4
- package/src/contracts.ts +2 -2
- package/src/createFile.ts +18 -18
- package/src/createNewContainerOnExistingFile.ts +10 -10
- package/src/createNewUtils.ts +13 -13
- package/src/epochTracker.ts +21 -21
- package/src/fetch.ts +1 -1
- package/src/fetchSnapshot.ts +24 -24
- package/src/getFileLink.ts +1 -1
- package/src/localOdspDriver/localOdspDeltaStorageService.ts +2 -2
- package/src/localOdspDriver/localOdspDocumentService.ts +1 -1
- package/src/localOdspDriver/localOdspDocumentServiceFactory.ts +2 -2
- package/src/localOdspDriver/localOdspDocumentStorageManager.ts +3 -3
- package/src/odspCache.ts +4 -4
- package/src/odspDelayLoadedDeltaStream.ts +26 -22
- package/src/odspDeltaStorageService.ts +6 -6
- package/src/odspDocumentDeltaConnection.ts +17 -14
- package/src/odspDocumentService.ts +15 -15
- package/src/odspDocumentServiceFactory.ts +3 -3
- package/src/odspDocumentServiceFactoryCore.ts +14 -14
- package/src/odspDocumentServiceFactoryWithCodeSplit.ts +2 -2
- package/src/odspDocumentStorageManager.ts +22 -22
- package/src/odspDocumentStorageServiceBase.ts +4 -4
- package/src/odspDriverUrlResolver.ts +4 -4
- package/src/odspDriverUrlResolverForShareLink.ts +8 -8
- package/src/odspError.ts +2 -2
- package/src/odspFluidFileLink.ts +1 -1
- package/src/odspPublicUtils.ts +1 -1
- package/src/odspSnapshotParser.ts +1 -1
- package/src/odspSummaryUploadManager.ts +4 -4
- package/src/odspUtils.ts +25 -25
- package/src/opsCaching.ts +1 -1
- package/src/packageVersion.ts +1 -1
- package/src/prefetchLatestSnapshot.ts +12 -12
- package/src/retryErrorsStorageAdapter.ts +2 -2
- package/src/retryUtils.ts +1 -1
- package/src/vroom.ts +6 -6
- package/src/zipItDataRepresentationUtils.ts +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTests.spec.js","sourceRoot":"","sources":["../../src/test/epochTests.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { IDocumentStorageServicePolicies } from \"@fluidframework/driver-definitions\";\nimport {\n\tOdspErrorTypes,\n\tIOdspResolvedUrl,\n\tICacheEntry,\n\tIEntry,\n\tmaximumCacheDurationMs,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { ThrottlingError, type NonRetryableError } from \"@fluidframework/driver-utils\";\nimport { createChildLogger, type IFluidErrorBase } from \"@fluidframework/telemetry-utils\";\nimport { stub } from \"sinon\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"../contracts.js\";\nimport { EpochTracker } from \"../epochTracker.js\";\nimport { LocalPersistentCache } from \"../odspCache.js\";\nimport { getHashedDocumentId } from \"../odspPublicUtils.js\";\nimport * as odspUtilsModule from \"../odspUtils.js\";\nimport { mockFetchOk, mockFetchSingle, createResponse } from \"./mockFetch.js\";\n\nconst createUtLocalCache = (): LocalPersistentCache => new LocalPersistentCache();\n\ndescribe(\"Tests for Epoch Tracker\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst itemId = \"itemId\";\n\tlet epochTracker: EpochTracker;\n\tlet localCache: LocalPersistentCache;\n\tlet hashedDocumentId: string;\n\tconst resolvedUrl = {\n\t\tsiteUrl,\n\t\tdriveId,\n\t\titemId,\n\t\todspResolvedUrl: true,\n\t} as unknown as IOdspResolvedUrl;\n\n\tbefore(async () => {\n\t\thashedDocumentId = await getHashedDocumentId(driveId, itemId);\n\t});\n\n\tbeforeEach(() => {\n\t\tlocalCache = createUtLocalCache();\n\t\t// use null logger here as we expect errors\n\t\tepochTracker = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tcreateChildLogger(),\n\t\t);\n\t});\n\n\tafterEach(async () => {\n\t\tawait epochTracker.removeEntries().catch(() => {});\n\t});\n\n\tit(\"defaultCacheExpiryTimeoutMs <= maximumCacheDurationMs policy\", () => {\n\t\t// This is the maximum allowed value per the policy - 5 days\n\t\tconst expected: Exclude<\n\t\t\tIDocumentStorageServicePolicies[\"maximumCacheDurationMs\"],\n\t\t\tundefined\n\t\t> = 432000000;\n\n\t\tassert(maximumCacheDurationMs <= expected, \"Actual cache expiry used must meet the policy\");\n\t});\n\n\tit(\"Cache, old versions\", async () => {\n\t\tconst cacheEntry1: ICacheEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t\tfile: { docId: hashedDocumentId, resolvedUrl },\n\t\t};\n\t\tconst cacheEntry2: ICacheEntry = { ...cacheEntry1, key: \"key2\" };\n\t\tconst cacheValue1 = { val: \"val1\", cacheEntryTime: Date.now() };\n\t\tconst cacheValue2 = { val: \"val2\", cacheEntryTime: Date.now() };\n\t\tconst value1: IVersionedValueWithEpoch = {\n\t\t\tvalue: cacheValue1,\n\t\t\tfluidEpoch: \"epoch1\",\n\t\t\tversion: persistedCacheValueVersion,\n\t\t};\n\t\tconst value2 = {\n\t\t\tvalue: cacheValue2,\n\t\t\tfluidEpoch: \"epoch1\",\n\t\t\tversion: \"non-existing version\",\n\t\t};\n\t\tawait localCache.put(cacheEntry1, value1);\n\t\tawait localCache.put(cacheEntry2, value2);\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\t// This should not fail, just return nothing!\n\t\tawait epochTracker.get(cacheEntry2);\n\t\t// Make sure nothing changed as result of reading data.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\tassert((await epochTracker.get(cacheEntry2)) === undefined, \"Entry 2 should not exist\");\n\t});\n\n\tit(\"Epoch error when fetch error from cache should throw epoch error and clear cache\", async () => {\n\t\tconst cacheEntry1: ICacheEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t\tfile: { docId: hashedDocumentId, resolvedUrl },\n\t\t};\n\t\tconst cacheEntry2: ICacheEntry = { ...cacheEntry1, key: \"key2\" };\n\t\tconst cacheValue1 = { val: \"val1\", cacheEntryTime: Date.now() };\n\t\tconst cacheValue2 = { val: \"val2\", cacheEntryTime: Date.now() };\n\t\tconst value1: IVersionedValueWithEpoch = {\n\t\t\tvalue: cacheValue1,\n\t\t\tfluidEpoch: \"epoch1\",\n\t\t\tversion: persistedCacheValueVersion,\n\t\t};\n\t\tconst value2: IVersionedValueWithEpoch = {\n\t\t\tvalue: cacheValue2,\n\t\t\tfluidEpoch: \"epoch2\",\n\t\t\tversion: persistedCacheValueVersion,\n\t\t};\n\t\tawait localCache.put(cacheEntry1, value1);\n\t\tawait localCache.put(cacheEntry2, value2);\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\t// This should not fail, just return nothing!\n\t\tawait epochTracker.get(cacheEntry2);\n\t\t// Make sure nothing changed as result of reading data.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\tassert((await epochTracker.get(cacheEntry2)) === undefined, \"Entry 2 should not exist\");\n\t});\n\n\tit(\"Epoch error when fetch response and should clear cache\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchArray(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch2\" },\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.fileOverwrittenInStorage,\n\t\t\t\t\"Error should be epoch error\",\n\t\t\t);\n\t\t}\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === undefined,\n\t\t\t\"Entry in cache should be cleared\",\n\t\t);\n\t\tassert.strictEqual(success, false, \"Fetching should fail!!\");\n\t});\n\n\tit(\"Epoch error when fetch response as json and should clear cache\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch2\" },\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.fileOverwrittenInStorage,\n\t\t\t\t\"Error should be epoch error\",\n\t\t\t);\n\t\t}\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === undefined,\n\t\t\t\"Entry in cache should be cleared\",\n\t\t);\n\t\tassert.strictEqual(success, false, \"Fetching should fail!!\");\n\t});\n\n\tit(\"Check client correlationID on error in unsuccessful fetch case\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch2\" },\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\tsuccess = false;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\tassert(error.XRequestStatsHeader !== undefined, \"CorrelationId should be present\");\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should fail!!\");\n\t});\n\n\tit(\"Check client correlationID on spoCommonHeaders in successful fetch case\", async () => {\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\tconst response = await mockFetchOk(\n\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t{},\n\t\t\t{ \"x-fluid-epoch\": \"epoch1\" },\n\t\t);\n\t\tassert(\n\t\t\tresponse.propsToLog.XRequestStatsHeader !== undefined,\n\t\t\t\"CorrelationId should be present\",\n\t\t);\n\t});\n\n\tit(\"Epoch error should not occur if response does not contain epoch\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(async () => epochTracker.fetchArray(\"fetchUrl\", {}, \"test\"));\n\t\t} catch {\n\t\t\tsuccess = false;\n\t\t}\n\t\tassert.strictEqual(success, true, \"Fetching should succeed!!\");\n\t\tassert.strictEqual(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, unicorn/no-await-expression-member\n\t\t\t(await epochTracker.get(cacheEntry1)).val,\n\t\t\t\"val1\",\n\t\t\t\"Entry in cache should be present\",\n\t\t);\n\t});\n\n\tit(\"Epoch error should not occur if response contains same epoch\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch1\" },\n\t\t\t);\n\t\t} catch {\n\t\t\tsuccess = false;\n\t\t}\n\t\tassert.strictEqual(success, true, \"Fetching should succeed!!\");\n\t\tassert.strictEqual(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, unicorn/no-await-expression-member\n\t\t\t(await epochTracker.get(cacheEntry1)).val,\n\t\t\t\"val1\",\n\t\t\t\"Entry in cache should be present\",\n\t\t);\n\t});\n\n\tit(\"Should differentiate between epoch and coherency 409 errors when coherency 409\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\tasync () => createResponse({ \"x-fluid-epoch\": \"epoch1\" }, undefined, 409),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.throttlingError,\n\t\t\t\t\"Error should be throttling error\",\n\t\t\t);\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should not succeed!!\");\n\t\tassert.strictEqual(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, unicorn/no-await-expression-member\n\t\t\t(await epochTracker.get(cacheEntry1)).val,\n\t\t\t\"val1\",\n\t\t\t\"Entry in cache should be present because it was not epoch 409\",\n\t\t);\n\t});\n\n\tit(\"Should differentiate between epoch and coherency 409 errors when epoch 409\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\tasync () => createResponse({ \"x-fluid-epoch\": \"epoch2\" }, undefined, 409),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.fileOverwrittenInStorage,\n\t\t\t\t\"Error should be epoch error\",\n\t\t\t);\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should not succeed!!\");\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === undefined,\n\t\t\t\"Entry in cache should be absent because it was epoch 409\",\n\t\t);\n\t});\n\n\tit(\"Check for resolved url on LocationRedirection error\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst newSiteUrl = \"https://microsoft.sharepoint.com/siteUrl\";\n\t\ttry {\n\t\t\tawait mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\tasync () =>\n\t\t\t\t\tcreateResponse(\n\t\t\t\t\t\t{ \"x-fluid-epoch\": \"epoch1\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\t\"message\": \"locationMoved\",\n\t\t\t\t\t\t\t\t\"@error.redirectLocation\": newSiteUrl,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t404,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.locationRedirection,\n\t\t\t\t\"Error should be locationRedirection error\",\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\tconst newResolvedUrl: IOdspResolvedUrl = (error as any).redirectUrl;\n\t\t\tassert.strictEqual(newResolvedUrl.siteUrl, newSiteUrl, \"New site url should match\");\n\t\t\tassert.strictEqual(newResolvedUrl.driveId, driveId, \"driveId should remain same\");\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should not succeed!!\");\n\t});\n\n\tit(\"Checks throttling errors are non-retriable when disableRetriesOnStorageThrottlingError=true\", async () => {\n\t\tconst retryAfterSeconds = 1;\n\t\tlet fetchStub;\n\t\tconst epochTrackerWithHostPolicy = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tcreateChildLogger(),\n\t\t\tundefined,\n\t\t\t{ disableRetriesOnStorageThrottlingError: true } /* hostPolicy */,\n\t\t);\n\t\ttry {\n\t\t\t// fetchHelper is used by epochTracker's fetch method, which we stub here to emulate throttling error\n\t\t\tfetchStub = stub(odspUtilsModule, \"fetchHelper\");\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.callsFake(async () => {\n\t\t\t\tthrow new ThrottlingError(\"Server is throttled\", retryAfterSeconds, {\n\t\t\t\t\ttestProp: \"testProp\",\n\t\t\t\t\tdriverVersion: \"1\",\n\t\t\t\t});\n\t\t\t});\n\t\t\tawait epochTrackerWithHostPolicy.fetch(\"fetchUrl\", {}, \"test\");\n\t\t} catch (error) {\n\t\t\t// retoring the fetchHelper function to avoid causing errors in other tests\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.restore();\n\t\t\tassert(\n\t\t\t\t(error as NonRetryableError<string>).canRetry === false,\n\t\t\t\t\"Error should be marked as non-retriable\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n\t\t\t\t(error as any).retryAfterSeconds === retryAfterSeconds,\n\t\t\t\t\"retryAfterSeconds should exist\",\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"Checks throttling errors retriable when disableRetriesOnStorageThrottlingError=false\", async () => {\n\t\tlet fetchStub;\n\t\tconst epochTrackerWithHostPolicy = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tcreateChildLogger(),\n\t\t\tundefined,\n\t\t\t{ disableRetriesOnStorageThrottlingError: false } /* hostPolicy */,\n\t\t);\n\t\ttry {\n\t\t\t// fetchHelper is used by epochTracker's fetch method, which we stub here to emulate throttling error\n\t\t\tfetchStub = stub(odspUtilsModule, \"fetchHelper\");\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.callsFake(async () => {\n\t\t\t\tthrow new ThrottlingError(\"Server is throttled\", 1000, {\n\t\t\t\t\ttestProp: \"testProp\",\n\t\t\t\t\tdriverVersion: \"1\",\n\t\t\t\t});\n\t\t\t});\n\t\t\tawait epochTrackerWithHostPolicy.fetch(\"fetchUrl\", {}, \"test\");\n\t\t} catch (error) {\n\t\t\t// retoring the fetchHelper function to avoid causing errors in other tests\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.restore();\n\t\t\tassert((error as ThrottlingError).canRetry === true, \"Error should be retriable\");\n\t\t}\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"epochTests.spec.js","sourceRoot":"","sources":["../../src/test/epochTests.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,EAA0B,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACvF,OAAO,EAIN,cAAc,EACd,sBAAsB,GACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAAwB,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAC1F,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAA4B,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,eAAe,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE9E,MAAM,kBAAkB,GAAG,GAAyB,EAAE,CAAC,IAAI,oBAAoB,EAAE,CAAC;AAElF,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACxC,MAAM,OAAO,GAAG,6CAA6C,CAAC;IAC9D,MAAM,OAAO,GAAG,SAAS,CAAC;IAC1B,MAAM,MAAM,GAAG,QAAQ,CAAC;IACxB,IAAI,YAA0B,CAAC;IAC/B,IAAI,UAAgC,CAAC;IACrC,IAAI,gBAAwB,CAAC;IAC7B,MAAM,WAAW,GAAG;QACnB,OAAO;QACP,OAAO;QACP,MAAM;QACN,eAAe,EAAE,IAAI;KACU,CAAC;IAEjC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,gBAAgB,GAAG,MAAM,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,UAAU,CAAC,GAAG,EAAE;QACf,UAAU,GAAG,kBAAkB,EAAE,CAAC;QAClC,2CAA2C;QAC3C,YAAY,GAAG,IAAI,YAAY,CAC9B,UAAU,EACV;YACC,KAAK,EAAE,gBAAgB;YACvB,WAAW;SACX,EACD,iBAAiB,EAAE,CACnB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACpB,MAAM,YAAY,CAAC,aAAa,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACvE,4DAA4D;QAC5D,MAAM,QAAQ,GAGV,SAAS,CAAC;QAEd,MAAM,CAAC,sBAAsB,IAAI,QAAQ,EAAE,+CAA+C,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,WAAW,GAAgB;YAChC,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE;SAC9C,CAAC;QACF,MAAM,WAAW,GAAgB,EAAE,GAAG,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QACjE,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAChE,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAChE,MAAM,MAAM,GAA6B;YACxC,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,0BAA0B;SACnC,CAAC;QACF,MAAM,MAAM,GAAG;YACd,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,sBAAsB;SAC/B,CAAC;QACF,MAAM,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1C,0DAA0D;QAC1D,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,WAAW,EACrD,kCAAkC,CAClC,CAAC;QACF,6CAA6C;QAC7C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,uDAAuD;QACvD,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,WAAW,EACrD,kCAAkC,CAClC,CAAC;QACF,MAAM,CAAC,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kFAAkF,EAAE,KAAK,IAAI,EAAE;QACjG,MAAM,WAAW,GAAgB;YAChC,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE;SAC9C,CAAC;QACF,MAAM,WAAW,GAAgB,EAAE,GAAG,WAAW,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QACjE,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAChE,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAChE,MAAM,MAAM,GAA6B;YACxC,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,0BAA0B;SACnC,CAAC;QACF,MAAM,MAAM,GAA6B;YACxC,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,QAAQ;YACpB,OAAO,EAAE,0BAA0B;SACnC,CAAC;QACF,MAAM,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,UAAU,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC1C,0DAA0D;QAC1D,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,WAAW,EACrD,kCAAkC,CAClC,CAAC;QACF,6CAA6C;QAC7C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,uDAAuD;QACvD,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,WAAW,EACrD,kCAAkC,CAClC,CAAC;QACF,MAAM,CAAC,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,SAAS,EAAE,0BAA0B,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACvE,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,WAAW,CAChB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EAC3D,EAAE,EACF,EAAE,eAAe,EAAE,QAAQ,EAAE,CAC7B,CAAC;SACF;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,CAAC,WAAW,CAChB,KAAkC,CAAC,SAAS,EAC7C,cAAc,CAAC,wBAAwB,EACvC,6BAA6B,CAC7B,CAAC;SACF;QACD,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,SAAS,EACnD,kCAAkC,CAClC,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC/E,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,WAAW,CAChB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,EAAE,EACF,EAAE,eAAe,EAAE,QAAQ,EAAE,CAC7B,CAAC;SACF;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,CAAC,WAAW,CAChB,KAAkC,CAAC,SAAS,EAC7C,cAAc,CAAC,wBAAwB,EACvC,6BAA6B,CAC7B,CAAC;SACF;QACD,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,SAAS,EACnD,kCAAkC,CAClC,CAAC;QACF,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC/E,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,WAAW,CAChB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,EAAE,EACF,EAAE,eAAe,EAAE,QAAQ,EAAE,CAC7B,CAAC;YACF,8DAA8D;SAC9D;QAAC,OAAO,KAAU,EAAE;YACpB,OAAO,GAAG,KAAK,CAAC;YAChB,sEAAsE;YACtE,MAAM,CAAC,KAAK,CAAC,mBAAmB,KAAK,SAAS,EAAE,iCAAiC,CAAC,CAAC;SACnF;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,MAAM,QAAQ,GAAG,MAAM,WAAW,CACjC,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,EAAE,EACF,EAAE,eAAe,EAAE,QAAQ,EAAE,CAC7B,CAAC;QACF,MAAM,CACL,QAAQ,CAAC,UAAU,CAAC,mBAAmB,KAAK,SAAS,EACrD,iCAAiC,CACjC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAChF,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,WAAW,CAAC,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;SAC/E;QAAC,MAAM;YACP,OAAO,GAAG,KAAK,CAAC;SAChB;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,2BAA2B,CAAC,CAAC;QAC/D,MAAM,CAAC,WAAW;QACjB,0GAA0G;QAC1G,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EACzC,MAAM,EACN,kCAAkC,CAClC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;QAC7E,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,WAAW,CAChB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,EAAE,EACF,EAAE,eAAe,EAAE,QAAQ,EAAE,CAC7B,CAAC;SACF;QAAC,MAAM;YACP,OAAO,GAAG,KAAK,CAAC;SAChB;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,2BAA2B,CAAC,CAAC;QAC/D,MAAM,CAAC,WAAW;QACjB,0GAA0G;QAC1G,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EACzC,MAAM,EACN,kCAAkC,CAClC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC/F,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,eAAe,CACpB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,KAAK,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,eAAe,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CACzE,CAAC;SACF;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,CAAC,WAAW,CAChB,KAAkC,CAAC,SAAS,EAC7C,cAAc,CAAC,eAAe,EAC9B,kCAAkC,CAClC,CAAC;SACF;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,+BAA+B,CAAC,CAAC;QACpE,MAAM,CAAC,WAAW;QACjB,0GAA0G;QAC1G,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,EACzC,MAAM,EACN,+DAA+D,CAC/D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;QAC3F,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,WAAW,GAAW;YAC3B,GAAG,EAAE,MAAM;YACX,IAAI,EAAE,UAAU;SAChB,CAAC;QACF,YAAY,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;QACrD,0DAA0D;QAC1D,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACpC,IAAI;YACH,MAAM,eAAe,CACpB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,KAAK,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,eAAe,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CACzE,CAAC;SACF;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,CAAC,WAAW,CAChB,KAAkC,CAAC,SAAS,EAC7C,cAAc,CAAC,wBAAwB,EACvC,6BAA6B,CAC7B,CAAC;SACF;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,+BAA+B,CAAC,CAAC;QACpE,MAAM,CACL,CAAC,MAAM,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,SAAS,EACnD,0DAA0D,CAC1D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACpE,IAAI,OAAO,GAAY,IAAI,CAAC;QAC5B,MAAM,UAAU,GAAG,0CAA0C,CAAC;QAC9D,IAAI;YACH,MAAM,eAAe,CACpB,KAAK,IAAI,EAAE,CAAC,YAAY,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EACpE,KAAK,IAAI,EAAE,CACV,cAAc,CACb,EAAE,eAAe,EAAE,QAAQ,EAAE,EAC7B;gBACC,KAAK,EAAE;oBACN,SAAS,EAAE,eAAe;oBAC1B,yBAAyB,EAAE,UAAU;iBACrC;aACD,EACD,GAAG,CACH,CACF,CAAC;SACF;QAAC,OAAO,KAAc,EAAE;YACxB,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,CAAC,WAAW,CAChB,KAAkC,CAAC,SAAS,EAC7C,cAAc,CAAC,mBAAmB,EAClC,2CAA2C,CAC3C,CAAC;YACF,mJAAmJ;YACnJ,MAAM,cAAc,GAAsB,KAAa,CAAC,WAAW,CAAC;YACpE,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,2BAA2B,CAAC,CAAC;YACpF,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,4BAA4B,CAAC,CAAC;SAClF;QACD,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,+BAA+B,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6FAA6F,EAAE,KAAK,IAAI,EAAE;QAC5G,MAAM,iBAAiB,GAAG,CAAC,CAAC;QAC5B,IAAI,SAAS,CAAC;QACd,MAAM,0BAA0B,GAAG,IAAI,YAAY,CAClD,UAAU,EACV;YACC,KAAK,EAAE,gBAAgB;YACvB,WAAW;SACX,EACD,iBAAiB,EAAE,EACnB,SAAS,EACT,EAAE,sCAAsC,EAAE,IAAI,EAAE,CAAC,gBAAgB,CACjE,CAAC;QACF,IAAI;YACH,qGAAqG;YACrG,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;YACjD,yGAAyG;YACzG,SAAS,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;gBAC9B,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,iBAAiB,EAAE;oBACnE,QAAQ,EAAE,UAAU;oBACpB,aAAa,EAAE,GAAG;iBAClB,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,MAAM,0BAA0B,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;SAC/D;QAAC,OAAO,KAAK,EAAE;YACf,2EAA2E;YAC3E,yGAAyG;YACzG,SAAS,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CACJ,KAAmC,CAAC,QAAQ,KAAK,KAAK,EACvD,yCAAyC,CACzC,CAAC;YACF,MAAM;YACL,0GAA0G;YACzG,KAAa,CAAC,iBAAiB,KAAK,iBAAiB,EACtD,gCAAgC,CAChC,CAAC;SACF;IACF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sFAAsF,EAAE,KAAK,IAAI,EAAE;QACrG,IAAI,SAAS,CAAC;QACd,MAAM,0BAA0B,GAAG,IAAI,YAAY,CAClD,UAAU,EACV;YACC,KAAK,EAAE,gBAAgB;YACvB,WAAW;SACX,EACD,iBAAiB,EAAE,EACnB,SAAS,EACT,EAAE,sCAAsC,EAAE,KAAK,EAAE,CAAC,gBAAgB,CAClE,CAAC;QACF,IAAI;YACH,qGAAqG;YACrG,SAAS,GAAG,IAAI,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;YACjD,yGAAyG;YACzG,SAAS,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;gBAC9B,MAAM,IAAI,eAAe,CAAC,qBAAqB,EAAE,IAAI,EAAE;oBACtD,QAAQ,EAAE,UAAU;oBACpB,aAAa,EAAE,GAAG;iBAClB,CAAC,CAAC;YACJ,CAAC,CAAC,CAAC;YACH,MAAM,0BAA0B,CAAC,KAAK,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;SAC/D;QAAC,OAAO,KAAK,EAAE;YACf,2EAA2E;YAC3E,yGAAyG;YACzG,SAAS,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,CAAE,KAAyB,CAAC,QAAQ,KAAK,IAAI,EAAE,2BAA2B,CAAC,CAAC;SAClF;IACF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { IDocumentStorageServicePolicies } from \"@fluidframework/driver-definitions\";\nimport { type NonRetryableError, ThrottlingError } from \"@fluidframework/driver-utils\";\nimport {\n\tICacheEntry,\n\tIEntry,\n\tIOdspResolvedUrl,\n\tOdspErrorTypes,\n\tmaximumCacheDurationMs,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { type IFluidErrorBase, createChildLogger } from \"@fluidframework/telemetry-utils\";\nimport { stub } from \"sinon\";\nimport { IVersionedValueWithEpoch, persistedCacheValueVersion } from \"../contracts.js\";\nimport { EpochTracker } from \"../epochTracker.js\";\nimport { LocalPersistentCache } from \"../odspCache.js\";\nimport { getHashedDocumentId } from \"../odspPublicUtils.js\";\nimport * as odspUtilsModule from \"../odspUtils.js\";\nimport { createResponse, mockFetchOk, mockFetchSingle } from \"./mockFetch.js\";\n\nconst createUtLocalCache = (): LocalPersistentCache => new LocalPersistentCache();\n\ndescribe(\"Tests for Epoch Tracker\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst itemId = \"itemId\";\n\tlet epochTracker: EpochTracker;\n\tlet localCache: LocalPersistentCache;\n\tlet hashedDocumentId: string;\n\tconst resolvedUrl = {\n\t\tsiteUrl,\n\t\tdriveId,\n\t\titemId,\n\t\todspResolvedUrl: true,\n\t} as unknown as IOdspResolvedUrl;\n\n\tbefore(async () => {\n\t\thashedDocumentId = await getHashedDocumentId(driveId, itemId);\n\t});\n\n\tbeforeEach(() => {\n\t\tlocalCache = createUtLocalCache();\n\t\t// use null logger here as we expect errors\n\t\tepochTracker = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tcreateChildLogger(),\n\t\t);\n\t});\n\n\tafterEach(async () => {\n\t\tawait epochTracker.removeEntries().catch(() => {});\n\t});\n\n\tit(\"defaultCacheExpiryTimeoutMs <= maximumCacheDurationMs policy\", () => {\n\t\t// This is the maximum allowed value per the policy - 5 days\n\t\tconst expected: Exclude<\n\t\t\tIDocumentStorageServicePolicies[\"maximumCacheDurationMs\"],\n\t\t\tundefined\n\t\t> = 432000000;\n\n\t\tassert(maximumCacheDurationMs <= expected, \"Actual cache expiry used must meet the policy\");\n\t});\n\n\tit(\"Cache, old versions\", async () => {\n\t\tconst cacheEntry1: ICacheEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t\tfile: { docId: hashedDocumentId, resolvedUrl },\n\t\t};\n\t\tconst cacheEntry2: ICacheEntry = { ...cacheEntry1, key: \"key2\" };\n\t\tconst cacheValue1 = { val: \"val1\", cacheEntryTime: Date.now() };\n\t\tconst cacheValue2 = { val: \"val2\", cacheEntryTime: Date.now() };\n\t\tconst value1: IVersionedValueWithEpoch = {\n\t\t\tvalue: cacheValue1,\n\t\t\tfluidEpoch: \"epoch1\",\n\t\t\tversion: persistedCacheValueVersion,\n\t\t};\n\t\tconst value2 = {\n\t\t\tvalue: cacheValue2,\n\t\t\tfluidEpoch: \"epoch1\",\n\t\t\tversion: \"non-existing version\",\n\t\t};\n\t\tawait localCache.put(cacheEntry1, value1);\n\t\tawait localCache.put(cacheEntry2, value2);\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\t// This should not fail, just return nothing!\n\t\tawait epochTracker.get(cacheEntry2);\n\t\t// Make sure nothing changed as result of reading data.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\tassert((await epochTracker.get(cacheEntry2)) === undefined, \"Entry 2 should not exist\");\n\t});\n\n\tit(\"Epoch error when fetch error from cache should throw epoch error and clear cache\", async () => {\n\t\tconst cacheEntry1: ICacheEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t\tfile: { docId: hashedDocumentId, resolvedUrl },\n\t\t};\n\t\tconst cacheEntry2: ICacheEntry = { ...cacheEntry1, key: \"key2\" };\n\t\tconst cacheValue1 = { val: \"val1\", cacheEntryTime: Date.now() };\n\t\tconst cacheValue2 = { val: \"val2\", cacheEntryTime: Date.now() };\n\t\tconst value1: IVersionedValueWithEpoch = {\n\t\t\tvalue: cacheValue1,\n\t\t\tfluidEpoch: \"epoch1\",\n\t\t\tversion: persistedCacheValueVersion,\n\t\t};\n\t\tconst value2: IVersionedValueWithEpoch = {\n\t\t\tvalue: cacheValue2,\n\t\t\tfluidEpoch: \"epoch2\",\n\t\t\tversion: persistedCacheValueVersion,\n\t\t};\n\t\tawait localCache.put(cacheEntry1, value1);\n\t\tawait localCache.put(cacheEntry2, value2);\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\t// This should not fail, just return nothing!\n\t\tawait epochTracker.get(cacheEntry2);\n\t\t// Make sure nothing changed as result of reading data.\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === cacheValue1,\n\t\t\t\"Entry 1 should continue to exist\",\n\t\t);\n\t\tassert((await epochTracker.get(cacheEntry2)) === undefined, \"Entry 2 should not exist\");\n\t});\n\n\tit(\"Epoch error when fetch response and should clear cache\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchArray(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch2\" },\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.fileOverwrittenInStorage,\n\t\t\t\t\"Error should be epoch error\",\n\t\t\t);\n\t\t}\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === undefined,\n\t\t\t\"Entry in cache should be cleared\",\n\t\t);\n\t\tassert.strictEqual(success, false, \"Fetching should fail!!\");\n\t});\n\n\tit(\"Epoch error when fetch response as json and should clear cache\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch2\" },\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.fileOverwrittenInStorage,\n\t\t\t\t\"Error should be epoch error\",\n\t\t\t);\n\t\t}\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === undefined,\n\t\t\t\"Entry in cache should be cleared\",\n\t\t);\n\t\tassert.strictEqual(success, false, \"Fetching should fail!!\");\n\t});\n\n\tit(\"Check client correlationID on error in unsuccessful fetch case\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch2\" },\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t} catch (error: any) {\n\t\t\tsuccess = false;\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n\t\t\tassert(error.XRequestStatsHeader !== undefined, \"CorrelationId should be present\");\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should fail!!\");\n\t});\n\n\tit(\"Check client correlationID on spoCommonHeaders in successful fetch case\", async () => {\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\tconst response = await mockFetchOk(\n\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t{},\n\t\t\t{ \"x-fluid-epoch\": \"epoch1\" },\n\t\t);\n\t\tassert(\n\t\t\tresponse.propsToLog.XRequestStatsHeader !== undefined,\n\t\t\t\"CorrelationId should be present\",\n\t\t);\n\t});\n\n\tit(\"Epoch error should not occur if response does not contain epoch\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(async () => epochTracker.fetchArray(\"fetchUrl\", {}, \"test\"));\n\t\t} catch {\n\t\t\tsuccess = false;\n\t\t}\n\t\tassert.strictEqual(success, true, \"Fetching should succeed!!\");\n\t\tassert.strictEqual(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, unicorn/no-await-expression-member\n\t\t\t(await epochTracker.get(cacheEntry1)).val,\n\t\t\t\"val1\",\n\t\t\t\"Entry in cache should be present\",\n\t\t);\n\t});\n\n\tit(\"Epoch error should not occur if response contains same epoch\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchOk(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\t{},\n\t\t\t\t{ \"x-fluid-epoch\": \"epoch1\" },\n\t\t\t);\n\t\t} catch {\n\t\t\tsuccess = false;\n\t\t}\n\t\tassert.strictEqual(success, true, \"Fetching should succeed!!\");\n\t\tassert.strictEqual(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, unicorn/no-await-expression-member\n\t\t\t(await epochTracker.get(cacheEntry1)).val,\n\t\t\t\"val1\",\n\t\t\t\"Entry in cache should be present\",\n\t\t);\n\t});\n\n\tit(\"Should differentiate between epoch and coherency 409 errors when coherency 409\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\tasync () => createResponse({ \"x-fluid-epoch\": \"epoch1\" }, undefined, 409),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.throttlingError,\n\t\t\t\t\"Error should be throttling error\",\n\t\t\t);\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should not succeed!!\");\n\t\tassert.strictEqual(\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, unicorn/no-await-expression-member\n\t\t\t(await epochTracker.get(cacheEntry1)).val,\n\t\t\t\"val1\",\n\t\t\t\"Entry in cache should be present because it was not epoch 409\",\n\t\t);\n\t});\n\n\tit(\"Should differentiate between epoch and coherency 409 errors when epoch 409\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst cacheEntry1: IEntry = {\n\t\t\tkey: \"key1\",\n\t\t\ttype: \"snapshot\",\n\t\t};\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\t\t// This will set the initial epoch value in epoch tracker.\n\t\tawait epochTracker.get(cacheEntry1);\n\t\ttry {\n\t\t\tawait mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\tasync () => createResponse({ \"x-fluid-epoch\": \"epoch2\" }, undefined, 409),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.fileOverwrittenInStorage,\n\t\t\t\t\"Error should be epoch error\",\n\t\t\t);\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should not succeed!!\");\n\t\tassert(\n\t\t\t(await epochTracker.get(cacheEntry1)) === undefined,\n\t\t\t\"Entry in cache should be absent because it was epoch 409\",\n\t\t);\n\t});\n\n\tit(\"Check for resolved url on LocationRedirection error\", async () => {\n\t\tlet success: boolean = true;\n\t\tconst newSiteUrl = \"https://microsoft.sharepoint.com/siteUrl\";\n\t\ttry {\n\t\t\tawait mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"test\"),\n\t\t\t\tasync () =>\n\t\t\t\t\tcreateResponse(\n\t\t\t\t\t\t{ \"x-fluid-epoch\": \"epoch1\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\t\t\"message\": \"locationMoved\",\n\t\t\t\t\t\t\t\t\"@error.redirectLocation\": newSiteUrl,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t404,\n\t\t\t\t\t),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tsuccess = false;\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.locationRedirection,\n\t\t\t\t\"Error should be locationRedirection error\",\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\tconst newResolvedUrl: IOdspResolvedUrl = (error as any).redirectUrl;\n\t\t\tassert.strictEqual(newResolvedUrl.siteUrl, newSiteUrl, \"New site url should match\");\n\t\t\tassert.strictEqual(newResolvedUrl.driveId, driveId, \"driveId should remain same\");\n\t\t}\n\t\tassert.strictEqual(success, false, \"Fetching should not succeed!!\");\n\t});\n\n\tit(\"Checks throttling errors are non-retriable when disableRetriesOnStorageThrottlingError=true\", async () => {\n\t\tconst retryAfterSeconds = 1;\n\t\tlet fetchStub;\n\t\tconst epochTrackerWithHostPolicy = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tcreateChildLogger(),\n\t\t\tundefined,\n\t\t\t{ disableRetriesOnStorageThrottlingError: true } /* hostPolicy */,\n\t\t);\n\t\ttry {\n\t\t\t// fetchHelper is used by epochTracker's fetch method, which we stub here to emulate throttling error\n\t\t\tfetchStub = stub(odspUtilsModule, \"fetchHelper\");\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.callsFake(async () => {\n\t\t\t\tthrow new ThrottlingError(\"Server is throttled\", retryAfterSeconds, {\n\t\t\t\t\ttestProp: \"testProp\",\n\t\t\t\t\tdriverVersion: \"1\",\n\t\t\t\t});\n\t\t\t});\n\t\t\tawait epochTrackerWithHostPolicy.fetch(\"fetchUrl\", {}, \"test\");\n\t\t} catch (error) {\n\t\t\t// retoring the fetchHelper function to avoid causing errors in other tests\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.restore();\n\t\t\tassert(\n\t\t\t\t(error as NonRetryableError<string>).canRetry === false,\n\t\t\t\t\"Error should be marked as non-retriable\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n\t\t\t\t(error as any).retryAfterSeconds === retryAfterSeconds,\n\t\t\t\t\"retryAfterSeconds should exist\",\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"Checks throttling errors retriable when disableRetriesOnStorageThrottlingError=false\", async () => {\n\t\tlet fetchStub;\n\t\tconst epochTrackerWithHostPolicy = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tcreateChildLogger(),\n\t\t\tundefined,\n\t\t\t{ disableRetriesOnStorageThrottlingError: false } /* hostPolicy */,\n\t\t);\n\t\ttry {\n\t\t\t// fetchHelper is used by epochTracker's fetch method, which we stub here to emulate throttling error\n\t\t\tfetchStub = stub(odspUtilsModule, \"fetchHelper\");\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.callsFake(async () => {\n\t\t\t\tthrow new ThrottlingError(\"Server is throttled\", 1000, {\n\t\t\t\t\ttestProp: \"testProp\",\n\t\t\t\t\tdriverVersion: \"1\",\n\t\t\t\t});\n\t\t\t});\n\t\t\tawait epochTrackerWithHostPolicy.fetch(\"fetchUrl\", {}, \"test\");\n\t\t} catch (error) {\n\t\t\t// retoring the fetchHelper function to avoid causing errors in other tests\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access\n\t\t\tfetchStub.restore();\n\t\t\tassert((error as ThrottlingError).canRetry === true, \"Error should be retriable\");\n\t\t}\n\t});\n});\n"]}
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { strict as assert } from "node:assert";
|
|
6
6
|
import { Deferred } from "@fluidframework/core-utils";
|
|
7
|
-
import { MockLogger } from "@fluidframework/telemetry-utils";
|
|
8
7
|
import { OdspErrorTypes, snapshotKey, } from "@fluidframework/odsp-driver-definitions";
|
|
8
|
+
import { MockLogger } from "@fluidframework/telemetry-utils";
|
|
9
9
|
import { EpochTrackerWithRedemption } from "../epochTracker.js";
|
|
10
10
|
import { LocalPersistentCache } from "../odspCache.js";
|
|
11
11
|
import { getHashedDocumentId } from "../odspPublicUtils.js";
|
|
12
|
-
import { mockFetchSingle,
|
|
12
|
+
import { mockFetchMultiple, mockFetchSingle, notFound, okResponse, } from "./mockFetch.js";
|
|
13
13
|
class DeferralWithCallback extends Deferred {
|
|
14
14
|
constructor() {
|
|
15
15
|
super();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"epochTestsWithRedemption.spec.js","sourceRoot":"","sources":["../../src/test/epochTestsWithRedemption.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { Deferred } from \"@fluidframework/core-utils\";\nimport { MockLogger, type IFluidErrorBase } from \"@fluidframework/telemetry-utils\";\nimport {\n\tOdspErrorTypes,\n\tIOdspResolvedUrl,\n\tIEntry,\n\tsnapshotKey,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { EpochTrackerWithRedemption } from \"../epochTracker.js\";\nimport { LocalPersistentCache } from \"../odspCache.js\";\nimport { getHashedDocumentId } from \"../odspPublicUtils.js\";\nimport {\n\tmockFetchSingle,\n\tmockFetchMultiple,\n\tokResponse,\n\tnotFound,\n\tMockResponse,\n} from \"./mockFetch.js\";\n\nclass DeferralWithCallback extends Deferred<void> {\n\tprivate epochCallback: () => Promise<unknown> = async () => {};\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tpublic setCallback(epochCallback: () => Promise<unknown>): void {\n\t\tthis.epochCallback = epochCallback;\n\t}\n\n\tpublic get promise(): Promise<void> {\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\treturn this.epochCallback().then(() => super.promise);\n\t}\n}\n\ndescribe(\"Tests for Epoch Tracker With Redemption\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst itemId = \"itemId\";\n\tconst logger = new MockLogger();\n\tlet epochTracker: EpochTrackerWithRedemption;\n\tlet hashedDocumentId: string;\n\tlet epochCallback: DeferralWithCallback;\n\n\tbefore(async () => {\n\t\thashedDocumentId = await getHashedDocumentId(driveId, itemId);\n\t});\n\n\tbeforeEach(() => {\n\t\tconst resolvedUrl = {\n\t\t\tsiteUrl,\n\t\t\tdriveId,\n\t\t\titemId,\n\t\t\todspResolvedUrl: true,\n\t\t} as unknown as IOdspResolvedUrl;\n\t\tepochTracker = new EpochTrackerWithRedemption(\n\t\t\tnew LocalPersistentCache(),\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tlogger.toTelemetryLogger(),\n\t\t);\n\t});\n\n\tafterEach(async () => {\n\t\tawait epochTracker.removeEntries().catch(() => {});\n\t\tlogger.assertMatchNone([{ category: \"error\" }]);\n\t});\n\n\tdescribe(\"Test Suite 1\", () => {\n\t\tbeforeEach(() => {\n\t\t\tepochCallback = new DeferralWithCallback();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(epochTracker as any).treesLatestDeferral = epochCallback;\n\t\t});\n\t\tit(\"joinSession call should succeed on retrying after snapshot cached read succeeds\", async () => {\n\t\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\t\tconst cacheEntry1: IEntry = {\n\t\t\t\ttype: snapshotKey,\n\t\t\t\tkey: \"key1\",\n\t\t\t};\n\t\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\n\t\t\t// We will trigger a successful call to return the value set in the cache after the failed joinSession call\n\t\t\tepochCallback.setCallback(async () => epochTracker.get(cacheEntry1));\n\n\t\t\t// Initial joinSession call will return 404 but after the timeout, the call will be retried and succeed\n\t\t\tawait mockFetchMultiple(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"joinSession\"),\n\t\t\t\t[\n\t\t\t\t\tnotFound,\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tokResponse({ \"x-fluid-epoch\": \"epoch1\" }, {}),\n\t\t\t\t],\n\t\t\t);\n\t\t});\n\n\t\tit(\"joinSession call should succeed on retrying after any network call to the file succeeds\", async () => {\n\t\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\t\tconst cacheEntry1: IEntry = {\n\t\t\t\ttype: snapshotKey,\n\t\t\t\tkey: \"key1\",\n\t\t\t};\n\t\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\n\t\t\t// We will trigger a successful call to return the value set in the cache after the failed joinSession call\n\t\t\tepochCallback.setCallback(async () => {\n\t\t\t\treturn epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"treesLatest\");\n\t\t\t});\n\n\t\t\t// Initial joinSession call will return 404 but after the timeout, the call will be retried and succeed\n\t\t\tawait mockFetchMultiple(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"joinSession\"),\n\t\t\t\t[\n\t\t\t\t\tnotFound, // joinSession\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tokResponse({ \"x-fluid-epoch\": \"epoch1\" }, {}), // \"treesLatest\"\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tokResponse({ \"x-fluid-epoch\": \"epoch1\" }, {}), // \"joinSession\"\n\t\t\t\t],\n\t\t\t);\n\t\t});\n\n\t\tit(\"Requests should fail if joinSession call fails and the getLatest call also fails\", async () => {\n\t\t\tlet success: boolean = true;\n\n\t\t\ttry {\n\t\t\t\tepochCallback.setCallback(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait mockFetchSingle(\n\t\t\t\t\t\t\tasync () =>\n\t\t\t\t\t\t\t\tepochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"treesLatest\"),\n\t\t\t\t\t\t\tnotFound,\n\t\t\t\t\t\t\t\"internal\",\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\t\t\t\tOdspErrorTypes.fileNotFoundOrAccessDeniedError,\n\t\t\t\t\t\t\t\"Error should be file not found or access denied error\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tawait mockFetchSingle(\n\t\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"joinSession\"),\n\t\t\t\t\tasync () => notFound({ \"x-fluid-epoch\": \"epoch1\" }),\n\t\t\t\t\t\"external\",\n\t\t\t\t);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tsuccess = false;\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\t\tOdspErrorTypes.fileNotFoundOrAccessDeniedError,\n\t\t\t\t\t\"Error should be file not found or access denied error\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tassert.strictEqual(\n\t\t\t\tsuccess,\n\t\t\t\tfalse,\n\t\t\t\t\"Join session should fail if treesLatest call has failed\",\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"Tests Suite 2\", () => {\n\t\tit(\"Failed treesLatest call should not trigger unhandled rejection event\", async () => {\n\t\t\tconst treesLatestP = mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"treesLatest\"),\n\t\t\t\tnotFound,\n\t\t\t);\n\t\t\tawait assert.rejects(\n\t\t\t\ttreesLatestP,\n\t\t\t\t\"should fail without causing an unhandledRejection event.\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"epochTestsWithRedemption.spec.js","sourceRoot":"","sources":["../../src/test/epochTestsWithRedemption.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { Deferred } from \"@fluidframework/core-utils\";\nimport {\n\tIEntry,\n\tIOdspResolvedUrl,\n\tOdspErrorTypes,\n\tsnapshotKey,\n} from \"@fluidframework/odsp-driver-definitions\";\nimport { type IFluidErrorBase, MockLogger } from \"@fluidframework/telemetry-utils\";\nimport { EpochTrackerWithRedemption } from \"../epochTracker.js\";\nimport { LocalPersistentCache } from \"../odspCache.js\";\nimport { getHashedDocumentId } from \"../odspPublicUtils.js\";\nimport {\n\tMockResponse,\n\tmockFetchMultiple,\n\tmockFetchSingle,\n\tnotFound,\n\tokResponse,\n} from \"./mockFetch.js\";\n\nclass DeferralWithCallback extends Deferred<void> {\n\tprivate epochCallback: () => Promise<unknown> = async () => {};\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\tpublic setCallback(epochCallback: () => Promise<unknown>): void {\n\t\tthis.epochCallback = epochCallback;\n\t}\n\n\tpublic get promise(): Promise<void> {\n\t\t// eslint-disable-next-line @typescript-eslint/promise-function-async\n\t\treturn this.epochCallback().then(() => super.promise);\n\t}\n}\n\ndescribe(\"Tests for Epoch Tracker With Redemption\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst itemId = \"itemId\";\n\tconst logger = new MockLogger();\n\tlet epochTracker: EpochTrackerWithRedemption;\n\tlet hashedDocumentId: string;\n\tlet epochCallback: DeferralWithCallback;\n\n\tbefore(async () => {\n\t\thashedDocumentId = await getHashedDocumentId(driveId, itemId);\n\t});\n\n\tbeforeEach(() => {\n\t\tconst resolvedUrl = {\n\t\t\tsiteUrl,\n\t\t\tdriveId,\n\t\t\titemId,\n\t\t\todspResolvedUrl: true,\n\t\t} as unknown as IOdspResolvedUrl;\n\t\tepochTracker = new EpochTrackerWithRedemption(\n\t\t\tnew LocalPersistentCache(),\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tlogger.toTelemetryLogger(),\n\t\t);\n\t});\n\n\tafterEach(async () => {\n\t\tawait epochTracker.removeEntries().catch(() => {});\n\t\tlogger.assertMatchNone([{ category: \"error\" }]);\n\t});\n\n\tdescribe(\"Test Suite 1\", () => {\n\t\tbeforeEach(() => {\n\t\t\tepochCallback = new DeferralWithCallback();\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t(epochTracker as any).treesLatestDeferral = epochCallback;\n\t\t});\n\t\tit(\"joinSession call should succeed on retrying after snapshot cached read succeeds\", async () => {\n\t\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\t\tconst cacheEntry1: IEntry = {\n\t\t\t\ttype: snapshotKey,\n\t\t\t\tkey: \"key1\",\n\t\t\t};\n\t\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\n\t\t\t// We will trigger a successful call to return the value set in the cache after the failed joinSession call\n\t\t\tepochCallback.setCallback(async () => epochTracker.get(cacheEntry1));\n\n\t\t\t// Initial joinSession call will return 404 but after the timeout, the call will be retried and succeed\n\t\t\tawait mockFetchMultiple(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"joinSession\"),\n\t\t\t\t[\n\t\t\t\t\tnotFound,\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tokResponse({ \"x-fluid-epoch\": \"epoch1\" }, {}),\n\t\t\t\t],\n\t\t\t);\n\t\t});\n\n\t\tit(\"joinSession call should succeed on retrying after any network call to the file succeeds\", async () => {\n\t\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\t\tconst cacheEntry1: IEntry = {\n\t\t\t\ttype: snapshotKey,\n\t\t\t\tkey: \"key1\",\n\t\t\t};\n\t\t\tawait epochTracker.put(cacheEntry1, { val: \"val1\" });\n\n\t\t\t// We will trigger a successful call to return the value set in the cache after the failed joinSession call\n\t\t\tepochCallback.setCallback(async () => {\n\t\t\t\treturn epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"treesLatest\");\n\t\t\t});\n\n\t\t\t// Initial joinSession call will return 404 but after the timeout, the call will be retried and succeed\n\t\t\tawait mockFetchMultiple(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"joinSession\"),\n\t\t\t\t[\n\t\t\t\t\tnotFound, // joinSession\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tokResponse({ \"x-fluid-epoch\": \"epoch1\" }, {}), // \"treesLatest\"\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tokResponse({ \"x-fluid-epoch\": \"epoch1\" }, {}), // \"joinSession\"\n\t\t\t\t],\n\t\t\t);\n\t\t});\n\n\t\tit(\"Requests should fail if joinSession call fails and the getLatest call also fails\", async () => {\n\t\t\tlet success: boolean = true;\n\n\t\t\ttry {\n\t\t\t\tepochCallback.setCallback(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait mockFetchSingle(\n\t\t\t\t\t\t\tasync () =>\n\t\t\t\t\t\t\t\tepochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"treesLatest\"),\n\t\t\t\t\t\t\tnotFound,\n\t\t\t\t\t\t\t\"internal\",\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tassert.strictEqual(\n\t\t\t\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\t\t\t\tOdspErrorTypes.fileNotFoundOrAccessDeniedError,\n\t\t\t\t\t\t\t\"Error should be file not found or access denied error\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tawait mockFetchSingle(\n\t\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"joinSession\"),\n\t\t\t\t\tasync () => notFound({ \"x-fluid-epoch\": \"epoch1\" }),\n\t\t\t\t\t\"external\",\n\t\t\t\t);\n\t\t\t} catch (error: unknown) {\n\t\t\t\tsuccess = false;\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\t\tOdspErrorTypes.fileNotFoundOrAccessDeniedError,\n\t\t\t\t\t\"Error should be file not found or access denied error\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tassert.strictEqual(\n\t\t\t\tsuccess,\n\t\t\t\tfalse,\n\t\t\t\t\"Join session should fail if treesLatest call has failed\",\n\t\t\t);\n\t\t});\n\t});\n\n\tdescribe(\"Tests Suite 2\", () => {\n\t\tit(\"Failed treesLatest call should not trigger unhandled rejection event\", async () => {\n\t\t\tconst treesLatestP = mockFetchSingle(\n\t\t\t\tasync () => epochTracker.fetchAndParseAsJSON(\"fetchUrl\", {}, \"treesLatest\"),\n\t\t\t\tnotFound,\n\t\t\t);\n\t\t\tawait assert.rejects(\n\t\t\t\ttreesLatestP,\n\t\t\t\t\"should fail without causing an unhandledRejection event.\",\n\t\t\t);\n\t\t});\n\t});\n});\n"]}
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
*/
|
|
5
5
|
/* eslint-disable @typescript-eslint/dot-notation */
|
|
6
6
|
import { strict as assert } from "node:assert";
|
|
7
|
-
import { stub } from "sinon";
|
|
8
|
-
import { OdspErrorTypes } from "@fluidframework/odsp-driver-definitions";
|
|
9
|
-
import { createChildLogger, MockLogger, } from "@fluidframework/telemetry-utils";
|
|
10
7
|
import { stringToBuffer } from "@fluid-internal/client-utils";
|
|
8
|
+
import { OdspErrorTypes } from "@fluidframework/odsp-driver-definitions";
|
|
9
|
+
import { MockLogger, createChildLogger, } from "@fluidframework/telemetry-utils";
|
|
10
|
+
import { stub } from "sinon";
|
|
11
|
+
import { convertToCompactSnapshot } from "../compactSnapshotWriter.js";
|
|
12
|
+
import { createOdspUrl } from "../createOdspUrl.js";
|
|
11
13
|
import { EpochTracker } from "../epochTracker.js";
|
|
12
14
|
import * as fetchSnapshotImport from "../fetchSnapshot.js";
|
|
13
15
|
import { LocalPersistentCache, NonPersistentCache } from "../odspCache.js";
|
|
14
|
-
import { createCacheSnapshotKey } from "../odspUtils.js";
|
|
15
|
-
import { createOdspUrl } from "../createOdspUrl.js";
|
|
16
|
-
import { getHashedDocumentId } from "../odspPublicUtils.js";
|
|
17
|
-
import { OdspDriverUrlResolver } from "../odspDriverUrlResolver.js";
|
|
18
16
|
import { OdspDocumentStorageService } from "../odspDocumentStorageManager.js";
|
|
19
|
-
import {
|
|
17
|
+
import { OdspDriverUrlResolver } from "../odspDriverUrlResolver.js";
|
|
18
|
+
import { getHashedDocumentId } from "../odspPublicUtils.js";
|
|
19
|
+
import { createCacheSnapshotKey } from "../odspUtils.js";
|
|
20
20
|
import { createResponse } from "./mockFetch.js";
|
|
21
21
|
const createUtLocalCache = () => new LocalPersistentCache();
|
|
22
22
|
describe("Tests1 for snapshot fetch", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetchSnapshot.spec.js","sourceRoot":"","sources":["../../src/test/fetchSnapshot.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/dot-notation */\n\nimport { strict as assert } from \"node:assert\";\nimport { stub } from \"sinon\";\nimport { ISnapshot } from \"@fluidframework/driver-definitions\";\nimport { OdspErrorTypes, IOdspResolvedUrl } from \"@fluidframework/odsp-driver-definitions\";\nimport {\n\tcreateChildLogger,\n\tMockLogger,\n\ttype ITelemetryLoggerExt,\n\ttype IFluidErrorBase,\n} from \"@fluidframework/telemetry-utils\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { EpochTracker } from \"../epochTracker.js\";\nimport { HostStoragePolicyInternal } from \"../contracts.js\";\nimport * as fetchSnapshotImport from \"../fetchSnapshot.js\";\nimport { LocalPersistentCache, NonPersistentCache } from \"../odspCache.js\";\nimport { INewFileInfo, IOdspResponse, createCacheSnapshotKey } from \"../odspUtils.js\";\nimport { createOdspUrl } from \"../createOdspUrl.js\";\nimport { getHashedDocumentId } from \"../odspPublicUtils.js\";\nimport { OdspDriverUrlResolver } from \"../odspDriverUrlResolver.js\";\nimport { ISnapshotRequestAndResponseOptions } from \"../fetchSnapshot.js\";\nimport { OdspDocumentStorageService } from \"../odspDocumentStorageManager.js\";\nimport { convertToCompactSnapshot } from \"../compactSnapshotWriter.js\";\nimport { createResponse } from \"./mockFetch.js\";\n\nconst createUtLocalCache = (): LocalPersistentCache => new LocalPersistentCache();\n\ndescribe(\"Tests1 for snapshot fetch\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst itemId = \"itemId\";\n\tconst filePath = \"path\";\n\tlet epochTracker: EpochTracker;\n\tlet localCache: LocalPersistentCache;\n\tlet hashedDocumentId: string;\n\tlet service: OdspDocumentStorageService;\n\n\tconst resolvedUrl = {\n\t\tsiteUrl,\n\t\tdriveId,\n\t\titemId,\n\t\todspResolvedUrl: true,\n\t} as unknown as IOdspResolvedUrl;\n\n\tconst newFileParams: INewFileInfo = {\n\t\ttype: \"New\",\n\t\tdriveId,\n\t\tsiteUrl: \"https://www.localhost.xxx\",\n\t\tfilePath,\n\t\tfilename: \"filename\",\n\t};\n\n\tconst hostPolicy: HostStoragePolicyInternal = {\n\t\tsnapshotOptions: { timeout: 2000, mds: 1000 },\n\t\tsummarizerClient: true,\n\t\tfetchBinarySnapshotFormat: false,\n\t\tconcurrentSnapshotFetch: true,\n\t};\n\n\tconst resolver = new OdspDriverUrlResolver();\n\tconst nonPersistentCache = new NonPersistentCache();\n\tlet logger: ITelemetryLoggerExt;\n\tlet mockLogger: MockLogger;\n\tconst odspUrl = createOdspUrl({ ...newFileParams, itemId, dataStorePath: \"/\" });\n\n\tconst content: ISnapshot = {\n\t\tsnapshotTree: {\n\t\t\tid: \"id\",\n\t\t\tblobs: {},\n\t\t\ttrees: {},\n\t\t},\n\t\tblobContents: new Map(),\n\t\tops: [],\n\t\tsequenceNumber: 0,\n\t\tlatestSequenceNumber: 0,\n\t\tsnapshotFormatV: 1,\n\t};\n\n\tlet resolved: IOdspResolvedUrl;\n\tbefore(async () => {\n\t\thashedDocumentId = await getHashedDocumentId(driveId, itemId);\n\t});\n\n\tbeforeEach(async () => {\n\t\tlocalCache = createUtLocalCache();\n\t\tmockLogger = new MockLogger();\n\t\tlogger = createChildLogger({ logger: mockLogger });\n\t\t// use null logger here as we expect errors\n\t\tepochTracker = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tlogger,\n\t\t);\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tresolved = await resolver.resolve({ url: odspUrl });\n\t\tservice = new OdspDocumentStorageService(\n\t\t\tresolved,\n\t\t\tasync (_options) => \"token\",\n\t\t\tlogger,\n\t\t\ttrue,\n\t\t\t{ ...nonPersistentCache, persistedCache: epochTracker },\n\t\t\thostPolicy,\n\t\t\tepochTracker,\n\t\t\tasync () => {\n\t\t\t\treturn {};\n\t\t\t},\n\t\t\t() => \"tenantid/id\",\n\t\t);\n\t});\n\n\tafterEach(async () => {\n\t\tawait epochTracker.removeEntries().catch(() => {});\n\t});\n\n\tit(\"Mds limit check in fetch snapshot\", async () => {\n\t\tlet success = false;\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tassert(\n\t\t\t\t\tgetDownloadSnapshotStub.args[0][3]?.mds === undefined,\n\t\t\t\t\t\"mds should be undefined\",\n\t\t\t\t);\n\t\t\t\tsuccess = true;\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse({}, content, 200)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/json\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getVersions(null, 1),\n\t\t\t);\n\t\t} catch {\n\t\t\t// Drop error\n\t\t}\n\t\tassert(success, \"mds limit should not be set!!\");\n\t});\n\n\tit(\"Check error in snapshot content type\", async () => {\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse({}, content, 200)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"unknown\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getVersions(null, 1),\n\t\t\t);\n\t\t\tassert.fail(\"should throw incorrectServerResponse error\");\n\t\t} catch (error: unknown) {\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\"incorrectServerResponse should be received\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t\t(error as any).contentType,\n\t\t\t\t\"unknown\",\n\t\t\t\t\"content type should be unknown\",\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"GetSnapshot() should work in normal flow\", async () => {\n\t\tlet ungroupedData = false;\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t\tassert(\n\t\t\t\t\tgetDownloadSnapshotStub.args[0][2]?.length === 0,\n\t\t\t\t\t\"should ask for ungroupedData\",\n\t\t\t\t);\n\t\t\t\tungroupedData = true;\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [] }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\tassert(ungroupedData, \"should have asked for ungroupedData\");\n\t\tconst cachedValue = (await epochTracker.get(createCacheSnapshotKey(resolved))) as ISnapshot;\n\t\tassert(cachedValue.snapshotTree.id === \"SnapshotId\", \"snapshot should have been cached\");\n\t\tassert(service[\"blobCache\"].value.size > 0, \"blobs should be cached locally\");\n\t\tassert(service[\"commitCache\"].size > 0, \"no trees should be cached\");\n\t});\n\n\tit(\"GetSnapshot() should work but snapshot should not be cached locally if asked for custom groupId\", async () => {\n\t\tlet success = false;\n\t\tservice[\"firstSnapshotFetchCall\"] = false;\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t\tassert(\n\t\t\t\t\tgetDownloadSnapshotStub.args[0][2]?.[0] === \"g1\",\n\t\t\t\t\t\"should ask for g1 groupId\",\n\t\t\t\t);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [\"g1\"] }),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tconsole.log(\"error\", error);\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\tassert(success, \"should have asked for g1 group id\");\n\t\tassert(service[\"blobCache\"].value.size > 0, \"blobs should still be cached locally\");\n\t\tassert(service[\"commitCache\"].size === 0, \"no trees should be cached\");\n\t\tassert(\n\t\t\tmockLogger.matchEvents([\n\t\t\t\t{\n\t\t\t\t\teventName: \"ObtainSnapshotForGroup_end\",\n\t\t\t\t\tmethod: \"networkOnly\",\n\t\t\t\t\tfetchSource: \"noCache\",\n\t\t\t\t\tuseLegacyFlowWithoutGroups: false,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t\"unexpected events\",\n\t\t);\n\t});\n\n\tit(\"GetSnapshot() should not cache locally when specified in options\", async () => {\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [], cacheSnapshot: false }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\tconst cachedValue = (await epochTracker.get(createCacheSnapshotKey(resolved))) as ISnapshot;\n\t\tassert(cachedValue.snapshotTree.id === \"SnapshotId\", \"snapshot should have been cached\");\n\t\tassert(service[\"blobCache\"].value.size > 0, \"blobs should still be cached locally\");\n\t\tassert(service[\"commitCache\"].size === 0, \"no trees should be cached\");\n\t});\n\n\tit(\"GetSnapshot() should not consult cache when request is for a loading group\", async () => {\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [], cacheSnapshot: false }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\n\t\t// Fetch again for a groupId\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [\"g1\"], cacheSnapshot: false }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\t// Cache should not be consulted.\n\t\tassert(\n\t\t\tmockLogger.matchEvents([\n\t\t\t\t{\n\t\t\t\t\teventName: \"ObtainSnapshot_end\",\n\t\t\t\t\tmethod: \"network\",\n\t\t\t\t\tuseLegacyFlowWithoutGroups: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\teventName: \"ObtainSnapshotForGroup_end\",\n\t\t\t\t\tmethod: \"networkOnly\",\n\t\t\t\t\tfetchSource: \"noCache\",\n\t\t\t\t\tuseLegacyFlowWithoutGroups: false,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t\"unexpected events\",\n\t\t);\n\t});\n});\n\nconst snapshotTreeWithGroupId: ISnapshotTree = {\n\tid: \"SnapshotId\",\n\tblobs: {},\n\ttrees: {\n\t\t\".protocol\": {\n\t\t\tblobs: {},\n\t\t\ttrees: {},\n\t\t},\n\t\t\".app\": {\n\t\t\tblobs: { \".metadata\": \"bARD4RKvW4LL1KmaUKp6hUMSp\" },\n\t\t\ttrees: {\n\t\t\t\t\".channels\": {\n\t\t\t\t\tblobs: {},\n\t\t\t\t\ttrees: {\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tblobs: {},\n\t\t\t\t\t\t\ttrees: {\n\t\t\t\t\t\t\t\tdds: {\n\t\t\t\t\t\t\t\t\tblobs: {},\n\t\t\t\t\t\t\t\t\ttrees: {},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tgroupId: \"G3\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tunreferenced: true,\n\t\t\t\t\tgroupId: \"G2\",\n\t\t\t\t},\n\t\t\t\t\".blobs\": { blobs: {}, trees: {} },\n\t\t\t},\n\t\t\tunreferenced: true,\n\t\t\tgroupId: \"G4\",\n\t\t},\n\t},\n};\n\nconst blobContents = new Map<string, ArrayBuffer>([\n\t[\n\t\t\"bARD4RKvW4LL1KmaUKp6hUMSp\",\n\t\tstringToBuffer(JSON.stringify({ summaryFormatVersion: 1, gcFeature: 0 }), \"utf8\"),\n\t],\n]);\n"]}
|
|
1
|
+
{"version":3,"file":"fetchSnapshot.spec.js","sourceRoot":"","sources":["../../src/test/fetchSnapshot.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\n/* eslint-disable @typescript-eslint/dot-notation */\n\nimport { strict as assert } from \"node:assert\";\nimport { stringToBuffer } from \"@fluid-internal/client-utils\";\nimport { ISnapshot } from \"@fluidframework/driver-definitions\";\nimport { IOdspResolvedUrl, OdspErrorTypes } from \"@fluidframework/odsp-driver-definitions\";\nimport { ISnapshotTree } from \"@fluidframework/protocol-definitions\";\nimport {\n\ttype IFluidErrorBase,\n\ttype ITelemetryLoggerExt,\n\tMockLogger,\n\tcreateChildLogger,\n} from \"@fluidframework/telemetry-utils\";\nimport { stub } from \"sinon\";\nimport { convertToCompactSnapshot } from \"../compactSnapshotWriter.js\";\nimport { HostStoragePolicyInternal } from \"../contracts.js\";\nimport { createOdspUrl } from \"../createOdspUrl.js\";\nimport { EpochTracker } from \"../epochTracker.js\";\nimport * as fetchSnapshotImport from \"../fetchSnapshot.js\";\nimport { ISnapshotRequestAndResponseOptions } from \"../fetchSnapshot.js\";\nimport { LocalPersistentCache, NonPersistentCache } from \"../odspCache.js\";\nimport { OdspDocumentStorageService } from \"../odspDocumentStorageManager.js\";\nimport { OdspDriverUrlResolver } from \"../odspDriverUrlResolver.js\";\nimport { getHashedDocumentId } from \"../odspPublicUtils.js\";\nimport { INewFileInfo, IOdspResponse, createCacheSnapshotKey } from \"../odspUtils.js\";\nimport { createResponse } from \"./mockFetch.js\";\n\nconst createUtLocalCache = (): LocalPersistentCache => new LocalPersistentCache();\n\ndescribe(\"Tests1 for snapshot fetch\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst itemId = \"itemId\";\n\tconst filePath = \"path\";\n\tlet epochTracker: EpochTracker;\n\tlet localCache: LocalPersistentCache;\n\tlet hashedDocumentId: string;\n\tlet service: OdspDocumentStorageService;\n\n\tconst resolvedUrl = {\n\t\tsiteUrl,\n\t\tdriveId,\n\t\titemId,\n\t\todspResolvedUrl: true,\n\t} as unknown as IOdspResolvedUrl;\n\n\tconst newFileParams: INewFileInfo = {\n\t\ttype: \"New\",\n\t\tdriveId,\n\t\tsiteUrl: \"https://www.localhost.xxx\",\n\t\tfilePath,\n\t\tfilename: \"filename\",\n\t};\n\n\tconst hostPolicy: HostStoragePolicyInternal = {\n\t\tsnapshotOptions: { timeout: 2000, mds: 1000 },\n\t\tsummarizerClient: true,\n\t\tfetchBinarySnapshotFormat: false,\n\t\tconcurrentSnapshotFetch: true,\n\t};\n\n\tconst resolver = new OdspDriverUrlResolver();\n\tconst nonPersistentCache = new NonPersistentCache();\n\tlet logger: ITelemetryLoggerExt;\n\tlet mockLogger: MockLogger;\n\tconst odspUrl = createOdspUrl({ ...newFileParams, itemId, dataStorePath: \"/\" });\n\n\tconst content: ISnapshot = {\n\t\tsnapshotTree: {\n\t\t\tid: \"id\",\n\t\t\tblobs: {},\n\t\t\ttrees: {},\n\t\t},\n\t\tblobContents: new Map(),\n\t\tops: [],\n\t\tsequenceNumber: 0,\n\t\tlatestSequenceNumber: 0,\n\t\tsnapshotFormatV: 1,\n\t};\n\n\tlet resolved: IOdspResolvedUrl;\n\tbefore(async () => {\n\t\thashedDocumentId = await getHashedDocumentId(driveId, itemId);\n\t});\n\n\tbeforeEach(async () => {\n\t\tlocalCache = createUtLocalCache();\n\t\tmockLogger = new MockLogger();\n\t\tlogger = createChildLogger({ logger: mockLogger });\n\t\t// use null logger here as we expect errors\n\t\tepochTracker = new EpochTracker(\n\t\t\tlocalCache,\n\t\t\t{\n\t\t\t\tdocId: hashedDocumentId,\n\t\t\t\tresolvedUrl,\n\t\t\t},\n\t\t\tlogger,\n\t\t);\n\t\tepochTracker.setEpoch(\"epoch1\", true, \"test\");\n\t\tresolved = await resolver.resolve({ url: odspUrl });\n\t\tservice = new OdspDocumentStorageService(\n\t\t\tresolved,\n\t\t\tasync (_options) => \"token\",\n\t\t\tlogger,\n\t\t\ttrue,\n\t\t\t{ ...nonPersistentCache, persistedCache: epochTracker },\n\t\t\thostPolicy,\n\t\t\tepochTracker,\n\t\t\tasync () => {\n\t\t\t\treturn {};\n\t\t\t},\n\t\t\t() => \"tenantid/id\",\n\t\t);\n\t});\n\n\tafterEach(async () => {\n\t\tawait epochTracker.removeEntries().catch(() => {});\n\t});\n\n\tit(\"Mds limit check in fetch snapshot\", async () => {\n\t\tlet success = false;\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tassert(\n\t\t\t\t\tgetDownloadSnapshotStub.args[0][3]?.mds === undefined,\n\t\t\t\t\t\"mds should be undefined\",\n\t\t\t\t);\n\t\t\t\tsuccess = true;\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse({}, content, 200)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/json\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getVersions(null, 1),\n\t\t\t);\n\t\t} catch {\n\t\t\t// Drop error\n\t\t}\n\t\tassert(success, \"mds limit should not be set!!\");\n\t});\n\n\tit(\"Check error in snapshot content type\", async () => {\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse({}, content, 200)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"unknown\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getVersions(null, 1),\n\t\t\t);\n\t\t\tassert.fail(\"should throw incorrectServerResponse error\");\n\t\t} catch (error: unknown) {\n\t\t\tassert.strictEqual(\n\t\t\t\t(error as Partial<IFluidErrorBase>).errorType,\n\t\t\t\tOdspErrorTypes.incorrectServerResponse,\n\t\t\t\t\"incorrectServerResponse should be received\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n\t\t\t\t(error as any).contentType,\n\t\t\t\t\"unknown\",\n\t\t\t\t\"content type should be unknown\",\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"GetSnapshot() should work in normal flow\", async () => {\n\t\tlet ungroupedData = false;\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t\tassert(\n\t\t\t\t\tgetDownloadSnapshotStub.args[0][2]?.length === 0,\n\t\t\t\t\t\"should ask for ungroupedData\",\n\t\t\t\t);\n\t\t\t\tungroupedData = true;\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [] }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\tassert(ungroupedData, \"should have asked for ungroupedData\");\n\t\tconst cachedValue = (await epochTracker.get(createCacheSnapshotKey(resolved))) as ISnapshot;\n\t\tassert(cachedValue.snapshotTree.id === \"SnapshotId\", \"snapshot should have been cached\");\n\t\tassert(service[\"blobCache\"].value.size > 0, \"blobs should be cached locally\");\n\t\tassert(service[\"commitCache\"].size > 0, \"no trees should be cached\");\n\t});\n\n\tit(\"GetSnapshot() should work but snapshot should not be cached locally if asked for custom groupId\", async () => {\n\t\tlet success = false;\n\t\tservice[\"firstSnapshotFetchCall\"] = false;\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t\tassert(\n\t\t\t\t\tgetDownloadSnapshotStub.args[0][2]?.[0] === \"g1\",\n\t\t\t\t\t\"should ask for g1 groupId\",\n\t\t\t\t);\n\t\t\t\tsuccess = true;\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [\"g1\"] }),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tconsole.log(\"error\", error);\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\tassert(success, \"should have asked for g1 group id\");\n\t\tassert(service[\"blobCache\"].value.size > 0, \"blobs should still be cached locally\");\n\t\tassert(service[\"commitCache\"].size === 0, \"no trees should be cached\");\n\t\tassert(\n\t\t\tmockLogger.matchEvents([\n\t\t\t\t{\n\t\t\t\t\teventName: \"ObtainSnapshotForGroup_end\",\n\t\t\t\t\tmethod: \"networkOnly\",\n\t\t\t\t\tfetchSource: \"noCache\",\n\t\t\t\t\tuseLegacyFlowWithoutGroups: false,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t\"unexpected events\",\n\t\t);\n\t});\n\n\tit(\"GetSnapshot() should not cache locally when specified in options\", async () => {\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [], cacheSnapshot: false }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\tconst cachedValue = (await epochTracker.get(createCacheSnapshotKey(resolved))) as ISnapshot;\n\t\tassert(cachedValue.snapshotTree.id === \"SnapshotId\", \"snapshot should have been cached\");\n\t\tassert(service[\"blobCache\"].value.size > 0, \"blobs should still be cached locally\");\n\t\tassert(service[\"commitCache\"].size === 0, \"no trees should be cached\");\n\t});\n\n\tit(\"GetSnapshot() should not consult cache when request is for a loading group\", async () => {\n\t\tasync function mockDownloadSnapshot<T>(\n\t\t\t_response: Promise<ISnapshotRequestAndResponseOptions>,\n\t\t\tcallback: () => Promise<T>,\n\t\t): Promise<T> {\n\t\t\tconst getDownloadSnapshotStub = stub(fetchSnapshotImport, \"downloadSnapshot\");\n\t\t\tgetDownloadSnapshotStub.returns(_response);\n\t\t\ttry {\n\t\t\t\treturn await callback();\n\t\t\t} finally {\n\t\t\t\tgetDownloadSnapshotStub.restore();\n\t\t\t}\n\t\t}\n\t\tconst snapshot: ISnapshot = {\n\t\t\tblobContents,\n\t\t\tsnapshotTree: snapshotTreeWithGroupId,\n\t\t\tops: [],\n\t\t\tlatestSequenceNumber: 0,\n\t\t\tsequenceNumber: 0,\n\t\t\tsnapshotFormatV: 1,\n\t\t};\n\t\tconst odspResponse: IOdspResponse<Response> = {\n\t\t\tcontent: (await createResponse(\n\t\t\t\t{},\n\t\t\t\tconvertToCompactSnapshot(snapshot),\n\t\t\t\t200,\n\t\t\t)) as unknown as Response,\n\t\t\tduration: 10,\n\t\t\theaders: new Map([\n\t\t\t\t[\"x-fluid-epoch\", \"epoch1\"],\n\t\t\t\t[\"content-type\", \"application/ms-fluid\"],\n\t\t\t]),\n\t\t\tpropsToLog: {},\n\t\t};\n\t\tconst response: ISnapshotRequestAndResponseOptions = {\n\t\t\todspResponse,\n\t\t\trequestHeaders: {},\n\t\t\trequestUrl: siteUrl,\n\t\t};\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [], cacheSnapshot: false }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\n\t\t// Fetch again for a groupId\n\t\ttry {\n\t\t\tawait mockDownloadSnapshot(Promise.resolve(response), async () =>\n\t\t\t\tservice.getSnapshot({ loadingGroupIds: [\"g1\"], cacheSnapshot: false }),\n\t\t\t);\n\t\t} catch {\n\t\t\tassert.fail(\"the getSnapshot request should succeed\");\n\t\t}\n\t\t// Cache should not be consulted.\n\t\tassert(\n\t\t\tmockLogger.matchEvents([\n\t\t\t\t{\n\t\t\t\t\teventName: \"ObtainSnapshot_end\",\n\t\t\t\t\tmethod: \"network\",\n\t\t\t\t\tuseLegacyFlowWithoutGroups: false,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\teventName: \"ObtainSnapshotForGroup_end\",\n\t\t\t\t\tmethod: \"networkOnly\",\n\t\t\t\t\tfetchSource: \"noCache\",\n\t\t\t\t\tuseLegacyFlowWithoutGroups: false,\n\t\t\t\t},\n\t\t\t]),\n\t\t\t\"unexpected events\",\n\t\t);\n\t});\n});\n\nconst snapshotTreeWithGroupId: ISnapshotTree = {\n\tid: \"SnapshotId\",\n\tblobs: {},\n\ttrees: {\n\t\t\".protocol\": {\n\t\t\tblobs: {},\n\t\t\ttrees: {},\n\t\t},\n\t\t\".app\": {\n\t\t\tblobs: { \".metadata\": \"bARD4RKvW4LL1KmaUKp6hUMSp\" },\n\t\t\ttrees: {\n\t\t\t\t\".channels\": {\n\t\t\t\t\tblobs: {},\n\t\t\t\t\ttrees: {\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tblobs: {},\n\t\t\t\t\t\t\ttrees: {\n\t\t\t\t\t\t\t\tdds: {\n\t\t\t\t\t\t\t\t\tblobs: {},\n\t\t\t\t\t\t\t\t\ttrees: {},\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tgroupId: \"G3\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\tunreferenced: true,\n\t\t\t\t\tgroupId: \"G2\",\n\t\t\t\t},\n\t\t\t\t\".blobs\": { blobs: {}, trees: {} },\n\t\t\t},\n\t\t\tunreferenced: true,\n\t\t\tgroupId: \"G4\",\n\t\t},\n\t},\n};\n\nconst blobContents = new Map<string, ArrayBuffer>([\n\t[\n\t\t\"bARD4RKvW4LL1KmaUKp6hUMSp\",\n\t\tstringToBuffer(JSON.stringify({ summaryFormatVersion: 1, gcFeature: 0 }), \"utf8\"),\n\t],\n]);\n"]}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { strict as assert } from "node:assert";
|
|
6
6
|
import { MockLogger } from "@fluidframework/telemetry-utils";
|
|
7
7
|
import { getFileLink } from "../getFileLink.js";
|
|
8
|
-
import {
|
|
8
|
+
import { createResponse, mockFetchMultiple, mockFetchSingle, notFound, okResponse, } from "./mockFetch.js";
|
|
9
9
|
describe("getFileLink", () => {
|
|
10
10
|
const siteUrl = "https://microsoft.sharepoint-df.com/siteUrl";
|
|
11
11
|
const driveId = "driveId";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getFileLink.spec.js","sourceRoot":"","sources":["../../src/test/getFileLink.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,
|
|
1
|
+
{"version":3,"file":"getFileLink.spec.js","sourceRoot":"","sources":["../../src/test/getFileLink.spec.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from \"node:assert\";\nimport { MockLogger } from \"@fluidframework/telemetry-utils\";\nimport { getFileLink } from \"../getFileLink.js\";\nimport {\n\tMockResponse,\n\tcreateResponse,\n\tmockFetchMultiple,\n\tmockFetchSingle,\n\tnotFound,\n\tokResponse,\n} from \"./mockFetch.js\";\n\ndescribe(\"getFileLink\", () => {\n\tconst siteUrl = \"https://microsoft.sharepoint-df.com/siteUrl\";\n\tconst driveId = \"driveId\";\n\tconst logger = new MockLogger();\n\tconst storageTokenFetcher = async (): Promise<string> => \"StorageToken\";\n\tconst fileItemResponse = {\n\t\twebDavUrl: \"fetchDavUrl\",\n\t\twebUrl: \"fetchWebUrl\",\n\t\tsharepointIds: { listItemUniqueId: \"fetchFileId\" },\n\t};\n\n\tafterEach(() => {\n\t\tlogger.assertMatchNone([{ category: \"error\" }]);\n\t});\n\n\tit(\"should return share link with existing access\", async () => {\n\t\tconst result = await mockFetchMultiple(\n\t\t\tasync () =>\n\t\t\t\tgetFileLink(\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\t{ siteUrl, driveId, itemId: \"itemId4\" },\n\t\t\t\t\tlogger.toTelemetryLogger(),\n\t\t\t\t),\n\t\t\t[\n\t\t\t\tasync (): Promise<MockResponse> => okResponse({}, fileItemResponse),\n\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\tokResponse({}, { d: { directUrl: \"sharelink\" } }),\n\t\t\t],\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tresult,\n\t\t\t\"sharelink\",\n\t\t\t\"File link should match url returned from sharing information\",\n\t\t);\n\t});\n\n\tit(\"should reject if file web dav url is missing\", async () => {\n\t\tawait assert.rejects(\n\t\t\tmockFetchMultiple(\n\t\t\t\tasync () =>\n\t\t\t\t\tgetFileLink(\n\t\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\t\t{ siteUrl, driveId, itemId: \"itemId5\" },\n\t\t\t\t\t\tlogger.toTelemetryLogger(),\n\t\t\t\t\t),\n\t\t\t\t[\n\t\t\t\t\tasync (): Promise<MockResponse> => okResponse({}, {}),\n\t\t\t\t\t// We retry once on malformed response from server, so need a second response mocked.\n\t\t\t\t\tasync (): Promise<MockResponse> => okResponse({}, {}),\n\t\t\t\t],\n\t\t\t),\n\t\t\t\"File link should reject for malformed url\",\n\t\t);\n\t});\n\n\tit(\"should reject if file item is not found\", async () => {\n\t\tawait assert.rejects(\n\t\t\tmockFetchSingle(async () => {\n\t\t\t\treturn getFileLink(\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\t{ siteUrl, driveId, itemId: \"itemId6\" },\n\t\t\t\t\tlogger.toTelemetryLogger(),\n\t\t\t\t);\n\t\t\t}, notFound),\n\t\t\t\"File link should reject when not found\",\n\t\t);\n\t});\n\n\tit(\"should successfully retry\", async () => {\n\t\tconst result = await mockFetchMultiple(\n\t\t\tasync () =>\n\t\t\t\tgetFileLink(\n\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\t{ siteUrl, driveId, itemId: \"itemId7\" },\n\t\t\t\t\tlogger.toTelemetryLogger(),\n\t\t\t\t),\n\t\t\t[\n\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\tcreateResponse({ \"retry-after\": \"0.001\" }, undefined, 900),\n\t\t\t\tasync (): Promise<MockResponse> => okResponse({}, fileItemResponse),\n\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\tokResponse({}, { d: { directUrl: \"sharelink\" } }),\n\t\t\t],\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tresult,\n\t\t\t\"sharelink\",\n\t\t\t\"File link should match url returned from sharing information\",\n\t\t);\n\t\t// Should be present in cache now and subsequent calls should fetch from cache.\n\t\tconst sharelink2 = await getFileLink(\n\t\t\tstorageTokenFetcher,\n\t\t\t{ siteUrl, driveId, itemId: \"itemId7\" },\n\t\t\tlogger.toTelemetryLogger(),\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tsharelink2,\n\t\t\t\"sharelink\",\n\t\t\t\"File link should match url returned from sharing information from cache\",\n\t\t);\n\t});\n\n\tit(\"should successfully give up after 5 tries\", async () => {\n\t\tawait assert.rejects(\n\t\t\tmockFetchMultiple(\n\t\t\t\tasync () =>\n\t\t\t\t\tgetFileLink(\n\t\t\t\t\t\tstorageTokenFetcher,\n\t\t\t\t\t\t{ siteUrl, driveId, itemId: \"itemId7\" },\n\t\t\t\t\t\tlogger.toTelemetryLogger(),\n\t\t\t\t\t),\n\t\t\t\t[\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tcreateResponse({ \"retry-after\": \"0.001\" }, undefined, 900),\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tcreateResponse({ \"retry-after\": \"0.001\" }, undefined, 900),\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tcreateResponse({ \"retry-after\": \"0.001\" }, undefined, 900),\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tcreateResponse({ \"retry-after\": \"0.001\" }, undefined, 900),\n\t\t\t\t\tasync (): Promise<MockResponse> =>\n\t\t\t\t\t\tcreateResponse({ \"retry-after\": \"0.001\" }, undefined, 900),\n\t\t\t\t],\n\t\t\t),\n\t\t\t\"did not retries 5 times\",\n\t\t);\n\t});\n});\n"]}
|
|
@@ -3,17 +3,17 @@
|
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
5
|
import { strict as assert } from "node:assert";
|
|
6
|
+
import { delay } from "@fluidframework/core-utils";
|
|
6
7
|
import { maximumCacheDurationMs, } from "@fluidframework/odsp-driver-definitions";
|
|
7
8
|
import { createChildLogger } from "@fluidframework/telemetry-utils";
|
|
8
|
-
import { delay } from "@fluidframework/core-utils";
|
|
9
|
-
import { EpochTracker } from "../epochTracker.js";
|
|
10
9
|
import { persistedCacheValueVersion, } from "../contracts.js";
|
|
11
|
-
import { LocalPersistentCache, NonPersistentCache } from "../odspCache.js";
|
|
12
10
|
import { createOdspUrl } from "../createOdspUrl.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
11
|
+
import { EpochTracker } from "../epochTracker.js";
|
|
12
|
+
import { LocalPersistentCache, NonPersistentCache } from "../odspCache.js";
|
|
15
13
|
import { OdspDocumentStorageService, defaultSummarizerCacheExpiryTimeout, } from "../odspDocumentStorageManager.js";
|
|
16
|
-
import {
|
|
14
|
+
import { OdspDriverUrlResolver } from "../odspDriverUrlResolver.js";
|
|
15
|
+
import { getHashedDocumentId } from "../odspPublicUtils.js";
|
|
16
|
+
import { createResponse, mockFetchSingle, notFound } from "./mockFetch.js";
|
|
17
17
|
const createUtLocalCache = () => new LocalPersistentCache();
|
|
18
18
|
describe("Tests for snapshot fetch", () => {
|
|
19
19
|
const siteUrl = "https://microsoft.sharepoint-df.com/siteUrl";
|