-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New: version history in details tab #220
Changes from 2 commits
3369541
af475b6
6a6484e
b8ac724
e21e0ce
c84bb32
e42d966
7967df2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,15 @@ import FileAPI from './File'; | |
import WebLinkAPI from './WebLink'; | ||
import SearchAPI from './Search'; | ||
import RecentsAPI from './Recents'; | ||
import { DEFAULT_HOSTNAME_API, DEFAULT_HOSTNAME_UPLOAD, TYPE_FOLDER, TYPE_FILE, TYPE_WEBLINK } from '../constants'; | ||
import VersionsAPI from './Versions'; | ||
import { | ||
DEFAULT_HOSTNAME_API, | ||
DEFAULT_HOSTNAME_UPLOAD, | ||
TYPE_FOLDER, | ||
TYPE_FILE, | ||
TYPE_WEBLINK, | ||
TYPE_VERSIONS | ||
} from '../constants'; | ||
import type { Options, ItemType, ItemAPI } from '../flowTypes'; | ||
|
||
class APIFactory { | ||
|
@@ -56,6 +64,11 @@ class APIFactory { | |
*/ | ||
recentsAPI: RecentsAPI; | ||
|
||
/** | ||
* @property {VersionsAPI} | ||
*/ | ||
versionsAPI: VersionsAPI; | ||
|
||
/** | ||
* [constructor] | ||
* | ||
|
@@ -111,6 +124,10 @@ class APIFactory { | |
this.recentsAPI.destroy(); | ||
delete this.recentsAPI; | ||
} | ||
if (this.versionsAPI) { | ||
this.versionsAPI.destroy(); | ||
delete this.versionsAPI; | ||
} | ||
if (destroyCache) { | ||
this.options.cache = new Cache(); | ||
} | ||
|
@@ -145,6 +162,9 @@ class APIFactory { | |
case TYPE_WEBLINK: | ||
api = this.getWebLinkAPI(); | ||
break; | ||
case TYPE_VERSIONS: | ||
api = this.getVersionsAPI(); | ||
break; | ||
default: | ||
throw new Error('Unknown Type!'); | ||
} | ||
|
@@ -228,6 +248,15 @@ class APIFactory { | |
this.recentsAPI = new RecentsAPI(this.options); | ||
return this.recentsAPI; | ||
} | ||
|
||
/** | ||
* API for versions | ||
*/ | ||
getVersionsAPI(): VersionsAPI { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may have to extend/improve these get*API calls to optionally take a flag that prevents calling this.destroy(). Until now it wasn't really needed because most API calls were not really called in parallel. Called one at a time. But versions will be called in parallel to say the File api call. So calling destroy will destroy the other. Likewise I didn't want two API calls to muck with the same cached object, but in versions case its a diff cache object, so not a big deal from that perspective. Either that, or the call to getVersionAPI() should come in the fetch success callback of the file, so that its a serial call and not parallel. |
||
this.destroy(); | ||
this.versionsAPI = new VersionsAPI(this.options); | ||
return this.versionsAPI; | ||
} | ||
} | ||
|
||
export default APIFactory; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
import noop from 'lodash/noop'; | ||
import Base from './Base'; | ||
import { getBadItemError } from '../util/error'; | ||
import { ACCESS_NONE, CACHE_PREFIX_SEARCH, CACHE_PREFIX_FOLDER, TYPE_FOLDER } from '../constants'; | ||
import { ACCESS_NONE, CACHE_PREFIX_SEARCH, CACHE_PREFIX_FOLDER, TYPE_FOLDER, TYPED_ID_FILE_PREFIX } from '../constants'; | ||
import type Cache from '../util/Cache'; | ||
import type { BoxItem, FlattenedBoxItem, FlattenedBoxItemCollection, BoxItemPermission } from '../flowTypes'; | ||
|
||
|
@@ -309,6 +309,17 @@ class Item extends Base { | |
.then(this.shareSuccessHandler) | ||
.catch(this.errorHandler); | ||
} | ||
|
||
/** | ||
* Returns typed id for file. Useful for when | ||
* making file based XHRs where auth token | ||
* can be per file as used by Preview. | ||
* | ||
* @return {string} typed id for file | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be in File.js as before |
||
*/ | ||
getTypedFileId(id: string): string { | ||
return `${TYPED_ID_FILE_PREFIX}${id}`; | ||
} | ||
} | ||
|
||
export default Item; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/** | ||
* @flow | ||
* @file Helper for the box versions API | ||
* @author Box | ||
*/ | ||
|
||
import Item from './Item'; | ||
import type { FileVersions } from '../flowTypes'; | ||
|
||
class Versions extends Item { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should not extend Item |
||
/** | ||
* API URL for versions | ||
* | ||
* @param {string} [id] - a box file id | ||
* @return {string} base url for files | ||
*/ | ||
getUrl(id: string): string { | ||
if (!id) { | ||
throw new Error('Missing file id!'); | ||
} | ||
return `${this.getBaseApiUrl()}/files/${id}/versions`; | ||
} | ||
|
||
/** | ||
* Gets the versions for a box file | ||
* | ||
* @param {string} id - a box file id | ||
* @param {Function} successCallback - Function to call with results | ||
* @param {Function} errorCallback - Function to call with errors | ||
* @return {Promise} | ||
*/ | ||
versions(id: string, successCallback: Function, errorCallback: Function): Promise<void> { | ||
if (this.isDestroyed()) { | ||
return Promise.reject(); | ||
} | ||
|
||
// Make the XHR request | ||
// We only need the total_count for now | ||
return this.xhr | ||
.get({ | ||
id: this.getTypedFileId(id), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be referenced from FileAPI. |
||
url: this.getUrl(id) | ||
}) | ||
.then(({ data }: { data: FileVersions }) => { | ||
successCallback(data); | ||
}) | ||
.catch(errorCallback); | ||
} | ||
} | ||
|
||
export default Versions; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import Versions from '../Versions'; | ||
|
||
let versions; | ||
const versionsResponse = { total_count: 0, entries: [] }; | ||
|
||
describe('api/Versions', () => { | ||
beforeEach(() => { | ||
versions = new Versions({}); | ||
}); | ||
|
||
describe('getUrl()', () => { | ||
test('should throw when version api url without id', () => { | ||
expect(() => { | ||
versions.getUrl(); | ||
}).toThrow(); | ||
}); | ||
test('should return correct version api url with id', () => { | ||
expect(versions.getUrl('foo')).toBe('https://api.box.com/2.0/files/foo/versions'); | ||
}); | ||
}); | ||
|
||
describe('file()', () => { | ||
test('should not do anything if destroyed', () => { | ||
versions.isDestroyed = jest.fn().mockReturnValueOnce(true); | ||
versions.xhr = null; | ||
|
||
const successCb = jest.fn(); | ||
const errorCb = jest.fn(); | ||
|
||
return versions.versions('id', successCb, errorCb).catch(() => { | ||
expect(successCb).not.toHaveBeenCalled(); | ||
expect(errorCb).not.toHaveBeenCalled(); | ||
}); | ||
}); | ||
|
||
test('should make xhr to get versions and call success callback', () => { | ||
versions.xhr = { | ||
get: jest.fn().mockReturnValueOnce(Promise.resolve({ data: versionsResponse })) | ||
}; | ||
|
||
const successCb = jest.fn(); | ||
|
||
return versions.versions('id', successCb).then(() => { | ||
expect(successCb).toHaveBeenCalledWith(versionsResponse); | ||
expect(versions.xhr.get).toHaveBeenCalledWith({ | ||
id: 'file_id', | ||
url: 'https://api.box.com/2.0/files/id/versions' | ||
}); | ||
}); | ||
}); | ||
|
||
test('should call error callback when xhr fails', () => { | ||
const error = new Error('error'); | ||
versions.xhr = { | ||
get: jest.fn().mockReturnValueOnce(Promise.reject(error)) | ||
}; | ||
|
||
const successCb = jest.fn(); | ||
const errorCb = jest.fn(); | ||
|
||
return versions.versions('id', successCb, errorCb).then(() => { | ||
expect(successCb).not.toHaveBeenCalled(); | ||
expect(errorCb).toHaveBeenCalledWith(error); | ||
expect(versions.xhr.get).toHaveBeenCalledWith({ | ||
id: 'file_id', | ||
url: 'https://api.box.com/2.0/files/id/versions' | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should not be here, as thats for item type only