|
| 1 | +import { expect } from 'chai'; |
| 2 | +import { |
| 3 | + stubEntitiesWithNestedFileWithPaths, |
| 4 | + stubEntitiesWithNoFilesWithPaths, |
| 5 | + stubEntitiesWithOneFileWithPaths, |
| 6 | + stubEntitiesWithPathsAndIndexInRoot, |
| 7 | + stubPublicEntitiesWithPaths, |
| 8 | + stubSpecialCharEntitiesWithPaths |
| 9 | +} from '../../tests/stubs'; |
| 10 | +import { stubTransactionID, W } from '../types'; |
| 11 | +import { ArFSFileToUpload, ArFSFolderToUpload, ArFSManifestToUpload, wrapFileOrFolder } from './arfs_file_wrapper'; |
| 12 | + |
| 13 | +describe('ArFSManifestToUpload class', () => { |
| 14 | + it('will link to an index.html file in the root of the folder if it exists', () => { |
| 15 | + const manifest = new ArFSManifestToUpload(stubEntitiesWithPathsAndIndexInRoot, 'DriveManifest.json'); |
| 16 | + |
| 17 | + // Ensure arweave required fields exist |
| 18 | + expect(manifest.manifest.manifest).to.equal('arweave/paths'); |
| 19 | + expect(manifest.manifest.version).to.equal('0.1.0'); |
| 20 | + |
| 21 | + // Expect index path to be linked to index.html |
| 22 | + expect(manifest.manifest.index.path).to.equal('index.html'); |
| 23 | + |
| 24 | + // Assert the structure is consistent with provided stub hierarchy |
| 25 | + expect(manifest.manifest.paths).to.deep.equal({ |
| 26 | + 'file-in-root': { |
| 27 | + id: '0000000000000000000000000000000000000000001' |
| 28 | + }, |
| 29 | + 'index.html': { |
| 30 | + id: '0000000000000000000000000000000000000000004' |
| 31 | + }, |
| 32 | + 'parent-folder/child-folder/file-in-child': { |
| 33 | + id: '0000000000000000000000000000000000000000003' |
| 34 | + }, |
| 35 | + 'parent-folder/file-in-parent': { |
| 36 | + id: '0000000000000000000000000000000000000000002' |
| 37 | + } |
| 38 | + }); |
| 39 | + }); |
| 40 | + |
| 41 | + it('constructs a manifest compatible with arweave gateways', () => { |
| 42 | + const manifest = new ArFSManifestToUpload(stubPublicEntitiesWithPaths, 'DriveManifest.json'); |
| 43 | + |
| 44 | + // Ensure arweave required fields exist |
| 45 | + expect(manifest.manifest.manifest).to.equal('arweave/paths'); |
| 46 | + expect(manifest.manifest.version).to.equal('0.1.0'); |
| 47 | + |
| 48 | + // Expect index path to be the first file |
| 49 | + expect(manifest.manifest.index.path).to.equal('file-in-root'); |
| 50 | + |
| 51 | + // Assert the structure is consistent with provided stub hierarchy |
| 52 | + expect(manifest.manifest.paths).to.deep.equal({ |
| 53 | + 'file-in-root': { |
| 54 | + id: '0000000000000000000000000000000000000000001' |
| 55 | + }, |
| 56 | + 'parent-folder/child-folder/file-in-child': { |
| 57 | + id: '0000000000000000000000000000000000000000003' |
| 58 | + }, |
| 59 | + 'parent-folder/file-in-parent': { |
| 60 | + id: '0000000000000000000000000000000000000000002' |
| 61 | + } |
| 62 | + }); |
| 63 | + }); |
| 64 | + |
| 65 | + it('throws an error when constructed with a hierarchy that has no file entities', () => { |
| 66 | + expect(() => new ArFSManifestToUpload(stubEntitiesWithNoFilesWithPaths, 'NameTestManifest.json')).to.throw( |
| 67 | + Error, |
| 68 | + 'Cannot construct a manifest of a folder that has no file entities!' |
| 69 | + ); |
| 70 | + }); |
| 71 | + |
| 72 | + it('getBaseFileName function returns the provided name', () => { |
| 73 | + const manifest = new ArFSManifestToUpload(stubPublicEntitiesWithPaths, 'NameTestManifest.json'); |
| 74 | + |
| 75 | + expect(manifest.getBaseFileName()).to.equal('NameTestManifest.json'); |
| 76 | + }); |
| 77 | + |
| 78 | + it('gatherFileInfo function returns the expected results', () => { |
| 79 | + const currentUnixTimeMs = Math.round(Date.now() / 1000); |
| 80 | + const manifest = new ArFSManifestToUpload(stubPublicEntitiesWithPaths, 'TestManifest.json'); |
| 81 | + |
| 82 | + const { dataContentType, lastModifiedDateMS, fileSize } = manifest.gatherFileInfo(); |
| 83 | + |
| 84 | + expect(dataContentType).to.equal('application/x.arweave-manifest+json'); |
| 85 | + expect(+lastModifiedDateMS).to.equal(currentUnixTimeMs); |
| 86 | + expect(+fileSize).to.equal(336); |
| 87 | + }); |
| 88 | + |
| 89 | + it('getFileDataBuffer function returns a compatible Buffer we can use to upload', () => { |
| 90 | + const manifest = new ArFSManifestToUpload(stubPublicEntitiesWithPaths, 'TestManifest.json'); |
| 91 | + |
| 92 | + expect(manifest.getFileDataBuffer() instanceof Buffer).to.be.true; |
| 93 | + }); |
| 94 | + |
| 95 | + describe('getLinksOutput function', () => { |
| 96 | + it('produces compatible links with a standard hierarchy', () => { |
| 97 | + const manifest = new ArFSManifestToUpload(stubPublicEntitiesWithPaths, 'TestManifest.json'); |
| 98 | + |
| 99 | + const linksOutput = manifest.getLinksOutput(stubTransactionID); |
| 100 | + |
| 101 | + expect(linksOutput.length).to.equal(4); |
| 102 | + expect(linksOutput[0]).to.equal(`https://arweave.net/${stubTransactionID}`); |
| 103 | + expect(linksOutput[1]).to.equal(`https://arweave.net/${stubTransactionID}/file-in-root`); |
| 104 | + expect(linksOutput[2]).to.equal( |
| 105 | + `https://arweave.net/${stubTransactionID}/parent-folder/child-folder/file-in-child` |
| 106 | + ); |
| 107 | + expect(linksOutput[3]).to.equal(`https://arweave.net/${stubTransactionID}/parent-folder/file-in-parent`); |
| 108 | + }); |
| 109 | + |
| 110 | + it('produces compatible links with a hierarchy of one single file', () => { |
| 111 | + const manifest = new ArFSManifestToUpload(stubEntitiesWithOneFileWithPaths, 'TestManifest.json'); |
| 112 | + |
| 113 | + const linksOutput = manifest.getLinksOutput(stubTransactionID); |
| 114 | + |
| 115 | + expect(linksOutput.length).to.equal(2); |
| 116 | + expect(linksOutput[0]).to.equal(`https://arweave.net/${stubTransactionID}`); |
| 117 | + expect(linksOutput[1]).to.equal(`https://arweave.net/${stubTransactionID}/file-in-root`); |
| 118 | + }); |
| 119 | + |
| 120 | + it('produces compatible links with a hierarchy of one nested file', () => { |
| 121 | + const manifest = new ArFSManifestToUpload(stubEntitiesWithNestedFileWithPaths, 'TestManifest.json'); |
| 122 | + |
| 123 | + const linksOutput = manifest.getLinksOutput(stubTransactionID); |
| 124 | + |
| 125 | + expect(linksOutput.length).to.equal(2); |
| 126 | + expect(linksOutput[0]).to.equal(`https://arweave.net/${stubTransactionID}`); |
| 127 | + expect(linksOutput[1]).to.equal( |
| 128 | + `https://arweave.net/${stubTransactionID}/parent-folder/child-folder/file-in-child` |
| 129 | + ); |
| 130 | + }); |
| 131 | + |
| 132 | + it('produces compatible links with a hierarchy of entities with special characters', () => { |
| 133 | + const manifest = new ArFSManifestToUpload(stubSpecialCharEntitiesWithPaths, 'TestManifest.json'); |
| 134 | + |
| 135 | + const linksOutput = manifest.getLinksOutput(stubTransactionID); |
| 136 | + |
| 137 | + expect(linksOutput.length).to.equal(4); |
| 138 | + expect(linksOutput[0]).to.equal(`https://arweave.net/${stubTransactionID}`); |
| 139 | + expect(linksOutput[1]).to.equal( |
| 140 | + `https://arweave.net/${stubTransactionID}/%25%26%40*(%25%26(%40*%3A%22%3E%3F%7B%7D%5B%5D` |
| 141 | + ); |
| 142 | + expect(linksOutput[2]).to.equal( |
| 143 | + `https://arweave.net/${stubTransactionID}/~!%40%23%24%25%5E%26*()_%2B%7B%7D%7C%5B%5D%3A%22%3B%3C%3E%3F%2C./%60/'/''_%5C___''_'__/'___'''_/QWERTYUIOPASDFGHJKLZXCVBNM!%40%23%24%25%5E%26*()_%2B%7B%7D%3A%22%3E%3F` |
| 144 | + ); |
| 145 | + expect(linksOutput[3]).to.equal( |
| 146 | + `https://arweave.net/${stubTransactionID}/~!%40%23%24%25%5E%26*()_%2B%7B%7D%7C%5B%5D%3A%22%3B%3C%3E%3F%2C./%60/dwijqndjqwnjNJKNDKJANKDNJWNJIvmnbzxnmvbcxvbm%2Cuiqwerioeqwndjkla` |
| 147 | + ); |
| 148 | + }); |
| 149 | + }); |
| 150 | +}); |
| 151 | + |
| 152 | +describe('ArFSFileToUpload class', () => { |
| 153 | + let fileToUpload: ArFSFileToUpload; |
| 154 | + |
| 155 | + beforeEach(() => { |
| 156 | + // Start each test with a newly wrapped file |
| 157 | + fileToUpload = wrapFileOrFolder('./test_wallet.json') as ArFSFileToUpload; |
| 158 | + }); |
| 159 | + |
| 160 | + it('throws an error on construction if file max size limit is exceeded', () => { |
| 161 | + expect( |
| 162 | + () => new ArFSFileToUpload('./test_wallet.json', { ...fileToUpload.fileStats, size: 2_147_483_647 }) |
| 163 | + ).to.throw(Error, 'Files greater than "2147483646" bytes are not yet supported!'); |
| 164 | + }); |
| 165 | + |
| 166 | + it('gatherFileInfo function returns the expected results', () => { |
| 167 | + const { dataContentType, fileSize, lastModifiedDateMS } = fileToUpload.gatherFileInfo(); |
| 168 | + |
| 169 | + expect(dataContentType).to.equal('application/json'); |
| 170 | + expect(+fileSize).to.equal(3204); |
| 171 | + |
| 172 | + // Last modified date varies between local dev environments and CI environment |
| 173 | + const expectedLastModifiedDate = fileToUpload.lastModifiedDate; |
| 174 | + expect(+lastModifiedDateMS).to.equal(+expectedLastModifiedDate); |
| 175 | + }); |
| 176 | + |
| 177 | + it('getFileDataBuffer function returns a compatible Buffer we can use to upload', () => { |
| 178 | + expect(fileToUpload.getFileDataBuffer() instanceof Buffer).to.be.true; |
| 179 | + }); |
| 180 | + |
| 181 | + it('getBaseFileName function returns the correct name', () => { |
| 182 | + expect(fileToUpload.getBaseFileName()).to.equal('test_wallet.json'); |
| 183 | + }); |
| 184 | + |
| 185 | + it('encryptedDataSize function returns the expected size', () => { |
| 186 | + expect(+fileToUpload.encryptedDataSize()).to.equal(3220); |
| 187 | + }); |
| 188 | + |
| 189 | + it('getBaseCosts function throws an error if base costs are not set', () => { |
| 190 | + expect(() => fileToUpload.getBaseCosts()).to.throw(Error, 'Base costs on file were never set!'); |
| 191 | + }); |
| 192 | + |
| 193 | + it('getBaseCosts function returns any assigned base costs', () => { |
| 194 | + fileToUpload.baseCosts = { fileDataBaseReward: W(1), metaDataBaseReward: W(2) }; |
| 195 | + |
| 196 | + expect(+fileToUpload.getBaseCosts().fileDataBaseReward).to.equal(1); |
| 197 | + expect(+fileToUpload.getBaseCosts().metaDataBaseReward).to.equal(2); |
| 198 | + }); |
| 199 | +}); |
| 200 | + |
| 201 | +describe('ArFSFolderToUpload class', () => { |
| 202 | + let folderToUpload: ArFSFolderToUpload; |
| 203 | + |
| 204 | + beforeEach(() => { |
| 205 | + // Start each test with a newly wrapped folder |
| 206 | + folderToUpload = wrapFileOrFolder('./tests/stub_files/bulk_root_folder') as ArFSFolderToUpload; |
| 207 | + }); |
| 208 | + |
| 209 | + it('getTotalByteCount function returns the expected size', () => { |
| 210 | + expect(+folderToUpload.getTotalByteCount()).to.equal(52); |
| 211 | + }); |
| 212 | + |
| 213 | + it('getTotalByteCount function returns the expected size if files are to be encrypted', () => { |
| 214 | + expect(+folderToUpload.getTotalByteCount(true)).to.equal(116); |
| 215 | + }); |
| 216 | + |
| 217 | + it('getBaseFileName function returns the correct name', () => { |
| 218 | + expect(folderToUpload.getBaseFileName()).to.equal('bulk_root_folder'); |
| 219 | + }); |
| 220 | + |
| 221 | + it('getBaseCosts function throws an error if base costs are not set', () => { |
| 222 | + expect(() => folderToUpload.getBaseCosts()).to.throw(Error, 'Base costs on folder were never set!'); |
| 223 | + }); |
| 224 | + |
| 225 | + it('getBaseCosts function returns any assigned base costs', () => { |
| 226 | + folderToUpload.baseCosts = { metaDataBaseReward: W(1) }; |
| 227 | + |
| 228 | + expect(+folderToUpload.getBaseCosts().metaDataBaseReward).to.equal(1); |
| 229 | + }); |
| 230 | +}); |
0 commit comments