import { strict as assert } from "assert" ; import { BlobTreeEntry , TreeTreeEntry } from "@fluidframework/protocol-base" ; import { IBlob , ITree } from "@fluidframework/protocol-definitions" ; import { gcBlobKey , getNormalizedSnapshot , ISnapshotNormalizerConfig } from "../snapshotNormalizer" ; describe ( "Snapshot Normalizer" , ( ) => { it ( "can normalize tree entries" , ( ) => { const snapshot = { id : "root" , entries : [ new TreeTreeEntry ( "entry2" , { id : "subTree" , entries : [ ] } ) , new BlobTreeEntry ( "entry3" , "blob3" ) , new BlobTreeEntry ( "entry1" , "blob1" ) , ] } ; const normalizedSnapshot = getNormalizedSnapshot ( snapshot ) ; assert . strictEqual ( normalizedSnapshot . entries [ 0 ] . path , "entry1" , "Snapshot tree entries not sorted" ) ; assert . strictEqual ( normalizedSnapshot . entries [ 1 ] . path , "entry2" , "Snapshot tree entries not sorted" ) ; assert . strictEqual ( normalizedSnapshot . entries [ 2 ] . path , "entry3" , "Snapshot tree entries not sorted" ) ; } ) ; it ( "can normalize GC blobs" , ( ) => { const gcDetails = { isRootNode : true , gcNodes : { node2 : [ "node1" , "/" ] , node1 : [ "node2" , "/" ] } } ; const normalizedGCDetails = { isRootNode : true , gcNodes : { node1 : [ "/" , "node2" ] , node2 : [ "/" , "node1" ] } } ; const snapshot = { id : "root" , entries : [ new TreeTreeEntry ( "tree" , { id : "subTree" , entries : [ new BlobTreeEntry ( gcBlobKey , JSON . stringify ( gcDetails ) ) , ] } ) , new BlobTreeEntry ( gcBlobKey , JSON . stringify ( gcDetails ) ) , ] } ; const normalizedSnapshot = getNormalizedSnapshot ( snapshot ) ; assert . strictEqual ( normalizedSnapshot . entries [ 0 ] . path , gcBlobKey , "Snapshot tree entries not sorted" ) ; const gcBlob = normalizedSnapshot . entries [ 0 ] . value as IBlob ; assert . deepStrictEqual ( JSON . parse ( gcBlob . contents ) , normalizedGCDetails , "GC blob not normalized" ) ; const innerGCBlob = ( normalizedSnapshot . entries [ 1 ] . value as ITree ) . entries [ 0 ] . value as IBlob ; assert . deepStrictEqual ( JSON . parse ( innerGCBlob . contents ) , normalizedGCDetails , "Inner blob not normalized" ) ; } ) ; it ( "can normalize custom blobs with array of objects" , ( ) => { const blobContents = [ { id : "2" , content : { key : "2" , value : "two" } } , { id : "1" , content : { key : "1" , value : "one" } } , { id : "3" , content : { key : "3" , value : "three" } } , ] ; const normalizedBlobContents = [ { id : "1" , content : { key : "1" , value : "one" } } , { id : "2" , content : { key : "2" , value : "two" } } , { id : "3" , content : { key : "3" , value : "three" } } , ] ; const snapshot = { id : "root" , entries : [ new BlobTreeEntry ( "normalized" , JSON . stringify ( normalizedBlobContents ) ) , new BlobTreeEntry ( "custom" , JSON . stringify ( blobContents ) ) , ] } ; const config = { blobsToNormalize : [ "custom" , "normalized" ] } ; const normalizedSnapshot = getNormalizedSnapshot ( snapshot , config ) ; assert . strictEqual ( normalizedSnapshot . entries [ 0 ] . path , "custom" , "Snapshot tree entries not sorted" ) ; const customBlob = normalizedSnapshot . entries [ 0 ] . value as IBlob ; assert . deepStrictEqual ( JSON . parse ( customBlob . contents ) , normalizedBlobContents , "Custom blob not normalized" ) ; assert . strictEqual ( normalizedSnapshot . entries [ 1 ] . path , "normalized" ) ; const normalizedBlob = normalizedSnapshot . entries [ 0 ] . value as IBlob ; assert . deepStrictEqual ( JSON . parse ( normalizedBlob . contents ) , normalizedBlobContents , "Normalized blob changed" ) ; } ) ; it ( "can normalize custom blobs with object of arrays" , ( ) => { const blobContents = { array2 : [ "2" , "1" , "3" , "4" ] , array1 : [ "c" , "a" , "d" , "b" ] } ; const normalizedBlobContents = { array1 : [ "a" , "b" , "c" , "d" ] , array2 : [ "1" , "2" , "3" , "4" ] } ; const snapshot = { id : "root" , entries : [ new BlobTreeEntry ( "normalized" , JSON . stringify ( normalizedBlobContents ) ) , new BlobTreeEntry ( "custom" , JSON . stringify ( blobContents ) ) , ] } ; const config = { blobsToNormalize : [ "custom" , "normalized" ] } ; const normalizedSnapshot = getNormalizedSnapshot ( snapshot , config ) ; assert . strictEqual ( normalizedSnapshot . entries [ 0 ] . path , "custom" , "Snapshot tree entries not sorted" ) ; const customBlob = normalizedSnapshot . entries [ 0 ] . value as IBlob ; assert . deepStrictEqual ( JSON . parse ( customBlob . contents ) , normalizedBlobContents , "Custom blob not normalized" ) ; assert . strictEqual ( normalizedSnapshot . entries [ 1 ] . path , "normalized" ) ; const normalizedBlob = normalizedSnapshot . entries [ 0 ] . value as IBlob ; assert . deepStrictEqual ( JSON . parse ( normalizedBlob . contents ) , normalizedBlobContents , "Normalized blob changed" ) ; } ) ; it ( "can normalize blob whose contents are not objects" , ( ) => { const snapshot = { id : "root" , entries : [ new BlobTreeEntry ( "custom1" , "contents" ) , new BlobTreeEntry ( "custom2" , JSON . stringify ( "contents" ) ) , ] } ; const config = { blobsToNormalize : [ "custom1" , "custom2" ] } ; const normalizedSnapshot = getNormalizedSnapshot ( snapshot , config ) ; const customBlob1 = normalizedSnapshot . entries [ 0 ] . value as IBlob ; assert . strictEqual ( customBlob1 . contents , "contents" , "Blob with string not as expected" ) ; const customBlob2 = normalizedSnapshot . entries [ 1 ] . value as IBlob ; assert . strictEqual ( customBlob2 . contents , JSON . stringify ( "contents" ) , "Blob with JSON strigified string not as expected" ) ; } ) ; } ) ;