Skip to content

Commit

Permalink
strengthen support for .isFolder and add support for .isNew
Browse files Browse the repository at this point in the history
  • Loading branch information
DrPaulBrewer committed Jan 10, 2018
1 parent 89945e1 commit 7ba8b53
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 29 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,13 @@ This could delete all the accessible files with mimeType audio/mpeg
const mp3search = drive.x.searcher({mimeType:'audio/mpeg'});
const Jim = drive.x.janitor('files','deleted');
mp3search().then(Jim).catch((e)=>{}); // we're trusting Jim the Janitor to clean up a lot here, he might hit an API limit


## Additional properties in resolved file objects

`.isNew` is always set to `true` by `drive.x.upload2` and `drive.x.folderCreator` always and set to `true` conditionally by `drive.x.createPath`, `drive.x.folderFactory` if a new folder is created, and is not set (undefined/falsey) when the requested folder already exists.

`.isFolder` is set to `true` on searches and folder creation when mimeType in the returned metadata indicates the Google Drive folder mimeType.

## Tests

I'm going to try to stay sane and not post a set of encrypted API keys and tokens to get a green "build passing" travis badge.
Expand Down
23 changes: 19 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ module.exports = decoratedGoogleDrive;
function extensions(drive, request, rootFolderId, spaces){
const x = {};

function addNew(meta){
if (typeof(meta)==='object'){
meta.isNew = true;
}
return meta;
}

function addIsFolder(meta){
if ((typeof(meta)==='object') && (meta.mimeType)){
meta.isFolder = (meta.mimeType === folderMimeType);
}
return meta;
}

function driveAboutMe(_fields){
const fields = _fields || "user,storageQuota";
return pify(drive.about.get)({fields});
Expand Down Expand Up @@ -86,9 +100,8 @@ function extensions(drive, request, rootFolderId, spaces){
drive.files.list(params, function(err, resp){
if (err) return reject(err);
// add isFolder boolean property to files, comparing mimeType to the Google Drive folder mimeType
if ((resp.files) && (resp.files.length))
for(var i=0,l=resp.files.length; i<l; ++i)
resp.files[i].isFolder = (resp.files[i].mimeType===folderMimeType);
if (Array.isArray(resp.files))
resp.files.forEach(addIsFolder);
const result = { parent, name, searchTerms, limit, unique, isSearchResult: true, files: resp.files };
return resolve(result);
});
Expand Down Expand Up @@ -176,7 +189,7 @@ function extensions(drive, request, rootFolderId, spaces){
return pify(drive.files.create)({
resource: metadata,
fields: 'id, mimeType, name'
});
}).then(addNew).then(addIsFolder)
})
);
};
Expand Down Expand Up @@ -315,6 +328,8 @@ function extensions(drive, request, rootFolderId, spaces){
}
}
}
addNew(result);
addIsFolder(result);
resolve(result);
});
localStream.pipe(md5buddy).pipe(uploadRequest);
Expand Down
44 changes: 36 additions & 8 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,10 @@ describe('decorated-google-drive:', function(){
});
it("uploading the string to appDataFolder file myaccount should resolve with expected file metadata", function(){
uploadResult.should.be.type("object");
uploadResult.should.have.properties('id','name','mimeType');
uploadResult.should.have.properties('id','name','mimeType','isNew');
uploadResult.name.should.equal("myaccount");
uploadResult.mimeType.should.equal("text/plain");
uploadResult.isNew.should.equal(true);
});
it("drive.x.appDataFolder.searcher should report there is exactly one myaccount file in the folder and it should match upload file id", function(){
drive.x.appDataFolder.searcher({})('appDataFolder','myaccount').then((found)=>{
Expand Down Expand Up @@ -114,10 +115,11 @@ describe('decorated-google-drive:', function(){
});
it("uploading the README.md file to /path/to/test/Files/README.md should resolve with expected file metadata", function(){
uploadResult.should.be.type("object");
uploadResult.should.have.properties('id','name','mimeType');
uploadResult.should.have.properties('id','name','mimeType','isNew');
uploadResult.id.length.should.be.above(1);
uploadResult.name.should.equal("README.md");
uploadResult.mimeType.should.equal("text/plain");
uploadResult.isNew.should.equal(true);
});
});
describe(' after drive.x.upload2 ', function(){
Expand All @@ -126,6 +128,7 @@ describe('decorated-google-drive:', function(){
.then((info)=>{
assert.ok(Array.isArray(info.files), "info.files is array");
assert.ok(info.files.some((f)=>((f.mimeType===folderMimeType) && (f.name==='path') && f.isFolder)), "info.files contains folder 'path'");
assert.ok(!info.isNew, "info.isNew should be falsey or undefined");
})
);
});
Expand All @@ -137,6 +140,7 @@ describe('decorated-google-drive:', function(){
})('root').then((info)=>{
assert.ok(Array.isArray(info.files), "info.files is array");
assert.ok(info.files.some((f)=>((f.mimeType===folderMimeType) && (f.name==='path') && f.isFolder )), "info.files contains folder 'path'");
assert.ok(!info.isNew, "info.isNew should be falsey or undefined");
})
);
});
Expand All @@ -158,20 +162,34 @@ describe('decorated-google-drive:', function(){
isFolder: false
})().then((info)=>{
assert.ok(Array.isArray(info.files), "info.files is array");
assert.ok(info.files.some((f)=>((f.name==='README.md') && (!f.isFolder))));
assert.ok(info.files.some((f)=>((f.name==='README.md') && (!f.isFolder) && (!f.isNew))));
assert.ok(info.files.length>0, "info.files should be non-empty");
})
);
});

it("checking existence with drive.x.findPath should yield expected file metadata", function(){
it("checking existence of /path/to/test/Files/README.md with drive.x.findPath should yield expected file metadata", function(){
return drive.x.findPath("/path/to/test/Files/README.md").then((info)=>{
info.should.have.properties('id','name','mimeType');
info.should.have.properties('id','name','mimeType','isFolder');
info.isFolder.should.equal(false);
info.id.length.should.be.above(1);
info.name.should.equal("README.md");
info.mimeType.should.equal("text/plain");
assert.ok(!info.isNew, "info.isNew should be falsey or undefined");
});
});

it("checking existence of /path/to/test should yield expected folder metadata", function(){
return drive.x.findPath("/path/to/test").then((info)=>{
info.should.have.properties('id','name','mimeType','isFolder');
info.isFolder.should.equal(true);
info.id.length.should.be.above(1);
info.name.should.equal("test");
info.mimeType.should.equal(folderMimeType);
assert.ok(!info.isNew, "info.isNew should be falsey or undefined");
});
});

it('checking existence on wrong path should throw Boom.notfound', function(){
// note: folder names seem to ignore upper/lower case
return drive.x.findPath("/not/the/path/to/test/Files/README.md").then(
Expand Down Expand Up @@ -211,22 +229,24 @@ describe('decorated-google-drive:', function(){
});
it("uploading the test.zip file to /path/to/test/Files/test.zip should resolve with expected file metadata and md5 match", function(){
uploadResult.should.be.type("object");
uploadResult.should.have.properties('id','name','mimeType','md5Checksum','ourMD5');
uploadResult.should.have.properties('id','name','mimeType','md5Checksum','ourMD5','isNew','isFolder');
uploadResult.id.length.should.be.above(1);
uploadResult.name.should.equal("test.zip");
uploadResult.mimeType.should.equal("application/zip");
uploadResult.ourMD5.should.equal(uploadResult.md5Checksum);
uploadResult.ourMD5.should.equal(testMD5);
uploadResult.isNew.should.equal(true);
uploadResult.isFolder.should.equal(false);
});
});
describe(' create folder /path/to/test2 ', function(){
let test2Folder = null;
before(function(){
return drive.x.createPath('/path/to/test2').then((f)=>{ test2Folder=f; });
});
it(' the resolved folder object should be an object with props id, name, mimeType ' , function(){
it(' the resolved folder object should be an object with props id, name, mimeType, isFolder ' , function(){
test2Folder.should.be.type("object");
test2Folder.should.have.properties('id','name','mimeType');
test2Folder.should.have.properties('id','name','mimeType','isFolder','isNew');
});
it(' the folder.id should be a string with length >4 ',function(){
test2Folder.id.should.be.type('string');
Expand All @@ -238,6 +258,12 @@ describe('decorated-google-drive:', function(){
it(' the mimeType should be '+folderMimeType+' ', function(){
test2Folder.mimeType.should.equal(folderMimeType);
});
it( ' isNew should be true ', function(){
test2Folder.isNew.should.equal(true);
});
it( ' isFolder should be true ', function(){
test2Folder.isFolder.should.equal(true);
});
});
describe(' use folderId of /path/to/test2 to upload test.zip ', function(){
let uploadResult = null;
Expand All @@ -261,6 +287,8 @@ describe('decorated-google-drive:', function(){
uploadResult.id.length.should.be.above(1);
uploadResult.name.should.equal("test.zip");
uploadResult.mimeType.should.equal("application/zip");
uploadResult.isNew.should.equal(true);
uploadResult.isFolder.should.equal(false);
uploadResult.ourMD5.should.equal(uploadResult.md5Checksum);
uploadResult.ourMD5.should.equal(testMD5);
});
Expand Down
35 changes: 19 additions & 16 deletions testResults.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,43 @@
✓ drive should not be undefined
✓ drive.x should be an object
drive.x.aboutMe
✓ should return the test users email address (424ms)
✓ should return a storageQuota object with properties limit, usage (168ms)
✓ drive.about.get still works, as well, and the outputs match (173ms)
✓ should return the test users email address (434ms)
✓ should return a storageQuota object with properties limit, usage (210ms)
✓ drive.about.get still works, as well, and the outputs match (184ms)
drive.x.appDataFolder.upload2: upload a string to appDataFolder
✓ uploading the string to appDataFolder file myaccount should resolve with expected file metadata
✓ drive.x.appDataFolder.searcher should report there is exactly one myaccount file in the folder and it should match upload file id
✓ drive.x.appDataFolder.contents should resolve to contents Hello-World-Test-1-2-3
drive.x.upload2: upload a file README.md to Drive folder /path/to/test/Files
✓ uploading the README.md file to /path/to/test/Files/README.md should resolve with expected file metadata
after drive.x.upload2
✓ searching root for anything should yield folder 'path' with .isFolder===true (224ms)
✓ searching root for folders should yield folder 'path' with .isFolder===true (210ms)
✓ searching root for non-folders should be empty (200ms)
✓ searching all folders for any non-trashed file should be non-empty and include file README.md in results (197ms)
✓ checking existence with drive.x.findPath should yield expected file metadata (1117ms)
✓ checking existence on wrong path should throw Boom.notfound (236ms)
✓ searching root for anything should yield folder 'path' with .isFolder===true (199ms)
✓ searching root for folders should yield folder 'path' with .isFolder===true (202ms)
✓ searching root for non-folders should be empty (322ms)
✓ searching all folders for any non-trashed file should be non-empty and include file README.md in results (241ms)
✓ checking existence of /path/to/test/Files/README.md with drive.x.findPath should yield expected file metadata (1139ms)
✓ checking existence of /path/to/test should yield expected folder metadata (779ms)
✓ checking existence on wrong path should throw Boom.notfound (262ms)
✓ downloading content with drive.x.download should yield contents string including 'License: MIT' (1286ms)
✓ drive.x.upload2 uploading the file again with {clobber:false} will throw Boom.conflict error because file already exists (977ms)
✓ drive.x.upload2 uploading the file again with {clobber:false} will throw Boom.conflict error because file already exists (997ms)
drive.x.upload2: upload test/test.zip to Drive folder /path/to/test/Files
✓ uploading the test.zip file to /path/to/test/Files/test.zip should resolve with expected file metadata and md5 match
create folder /path/to/test2
✓ the resolved folder object should be an object with props id, name, mimeType
✓ the resolved folder object should be an object with props id, name, mimeType, isFolder
✓ the folder.id should be a string with length >4
✓ the folder.name should be "test2"
✓ the mimeType should be application/vnd.google-apps.folder
✓ isNew should be true
✓ isFolder should be true
use folderId of /path/to/test2 to upload test.zip
✓ uploading the test.zip file to /path/to/test2/test.zip should resolve with expected file metadata and md5 match
cleanup via drive.x.janitor
✓ janitor hopefully deletes the README.md file(s) OK and resolves correctly (1374ms)
✓ drive.x.findPath will throw Boom.notFound if the file was successfully deleted (1051ms)
✓ janitor will throw an error if told to delete an invalid file (136ms)
✓ janitor hopefully deletes the README.md file(s) OK and resolves correctly (1444ms)
✓ drive.x.findPath will throw Boom.notFound if the file was successfully deleted (1006ms)
✓ janitor will throw an error if told to delete an invalid file (144ms)
✓ janitor should not throw an error if given an empty filelist
✓ final cleanup: delete the path folder and check non-existence (2839ms)
✓ final cleanup: delete the path folder and check non-existence (1006ms)


29 passing (21s)
32 passing (20s)

0 comments on commit 7ba8b53

Please sign in to comment.