Skip to content

Commit

Permalink
fix: Saving a new Parse.Object with an unsaved Parse.File fails (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
swittk authored Feb 4, 2023
1 parent 528ef08 commit 16535a4
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 7 deletions.
19 changes: 19 additions & 0 deletions integration/test/ParseFileTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,23 @@ describe('Parse.File', () => {
assert.equal(e.code, Parse.Error.FILE_DELETE_ERROR);
}
});

it('can save file to localDatastore', async () => {
Parse.enableLocalDatastore();
const file = new Parse.File('parse-js-sdk', [61, 170, 236, 120]);
const object = new Parse.Object('TestObject');
await object.pin();

object.set('file', file);
await object.save();

const query = new Parse.Query(TestObject);
query.fromLocalDatastore();
const results = await query.find();

const url = results[0].get('file').url();
assert.equal(results.length, 1);
assert.notEqual(url, undefined);
assert.equal(url, file.url());
});
});
7 changes: 5 additions & 2 deletions src/ParseObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -2499,8 +2499,11 @@ const DefaultController = {
return Promise.reject(objectError);
}
for (const object of target) {
await localDatastore._updateLocalIdForObject(mapIdForPin[object.id], object);
await localDatastore._updateObjectIfPinned(object);
// Make sure that it is a ParseObject before updating it into the localDataStore
if (object instanceof ParseObject) {
await localDatastore._updateLocalIdForObject(mapIdForPin[object.id], object);
await localDatastore._updateObjectIfPinned(object);
}
}
return Promise.resolve(target);
});
Expand Down
33 changes: 32 additions & 1 deletion src/__tests__/ParseFile-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,21 @@ const mockHttp = require('http');
const mockHttps = require('https');

const mockLocalDatastore = {
_updateLocalIdForObject: jest.fn(),
_updateLocalIdForObject: jest.fn((localId, /** @type {ParseObject}*/ object) => {
if (!mockLocalDatastore.isEnabled) {
return;
}
/* eslint-disable no-unused-vars */
// (Taken from LocalDataStore source) This fails for nested objects that are not ParseObject
const objectKey = mockLocalDatastore.getKeyForObject(object);
}),
_updateObjectIfPinned: jest.fn(),
getKeyForObject: jest.fn((object) => {
// (Taken from LocalDataStore source) This fails for nested objects that are not ParseObject
const OBJECT_PREFIX = 'Parse_LDS_';
const objectId = object.objectId || object._getId();
return `${OBJECT_PREFIX}${object.className}_${objectId}`;
}),
};
jest.setMock('../LocalDatastore', mockLocalDatastore);

Expand All @@ -37,6 +50,8 @@ const defaultController = CoreManager.getFileController();

describe('ParseFile', () => {
beforeEach(() => {
ParseObject.enableSingleInstance();
jest.clearAllMocks();
CoreManager.setFileController({
saveFile: generateSaveMock('http://files.parsetfss.com/a/'),
saveBase64: generateSaveMock('http://files.parsetfss.com/a/'),
Expand Down Expand Up @@ -945,4 +960,20 @@ describe('FileController', () => {
}
global.FileReader = fileReader;
});

it('can save unsaved Parse.File property when localDataStore is enabled.', async () => {
mockLocalDatastore.isEnabled = true;
const obj = new ParseObject('Item');
const aFile = new ParseFile('myFileName', [0, 0, 0, 0, 2, 3, 4, 5]);
obj.set('myName', 'helloworld');
obj.set('myFile', aFile);
let error = undefined;
try {
await obj.save();
} catch (e) {
error = e;
}
expect(error).toBeUndefined();
expect(obj.get('myFile').name()).toBe('myFileName');
});
});
19 changes: 15 additions & 4 deletions src/__tests__/ParseObject-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,23 @@ const mockLocalDatastore = {
_serializeObjectsFromPinName: jest.fn(),
_serializeObject: jest.fn(),
_transverseSerializeObject: jest.fn(),
_updateObjectIfPinned: jest.fn(),
_destroyObjectIfPinned: jest.fn(),
_updateLocalIdForObject: jest.fn(),
updateFromServer: jest.fn(),
_updateLocalIdForObject: jest.fn((localId, /** @type {ParseObject}*/ object) => {
if (!mockLocalDatastore.isEnabled) {
return;
}
/* eslint-disable no-unused-vars */
// (Taken from LocalDataStore source) This fails for nested objects that are not ParseObject
const objectKey = mockLocalDatastore.getKeyForObject(object);
}),
_updateObjectIfPinned: jest.fn(),
getKeyForObject: jest.fn((object) => {
// (Taken from LocalDataStore source) This fails for nested objects that are not ParseObject
const objectId = object.objectId || object._getId();
const OBJECT_PREFIX = 'Parse_LDS_';
return `${OBJECT_PREFIX}${object.className}_${objectId}`;
}), updateFromServer: jest.fn(),
_clear: jest.fn(),
getKeyForObject: jest.fn(),
checkIfEnabled: jest.fn(() => {
if (!mockLocalDatastore.isEnabled) {
console.error('Parse.enableLocalDatastore() must be called first');
Expand Down

0 comments on commit 16535a4

Please sign in to comment.