Lists: use separate add/remove functions instead of toggle
This commit is contained in:
@@ -48,10 +48,39 @@ describe('Places Module', () => {
|
||||
const id = 'some-id';
|
||||
const geohash = 'u33dc0'; // u3/3d/
|
||||
|
||||
mockClient.getAll.mockResolvedValue([]);
|
||||
|
||||
await places.remove(id, geohash);
|
||||
|
||||
expect(mockClient.remove).toHaveBeenCalledWith('u3/3d/some-id');
|
||||
});
|
||||
|
||||
it('cleans up references from lists', async () => {
|
||||
const id = 'some-id';
|
||||
const geohash = 'u33dc0';
|
||||
|
||||
const mockLists = {
|
||||
'to-go': {
|
||||
id: 'to-go',
|
||||
placeRefs: [{ id: 'some-id', geohash: 'u33dc0' }],
|
||||
},
|
||||
'to-do': { id: 'to-do', placeRefs: [] },
|
||||
};
|
||||
mockClient.getAll.mockResolvedValue(Object.values(mockLists));
|
||||
|
||||
await places.remove(id, geohash);
|
||||
|
||||
expect(mockClient.getAll).toHaveBeenCalledWith('_lists/');
|
||||
|
||||
// Expect "to-go" to be updated without the reference
|
||||
expect(mockClient.storeObject).toHaveBeenCalledWith(
|
||||
'list',
|
||||
'_lists/to-go',
|
||||
expect.objectContaining({
|
||||
placeRefs: [],
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get', () => {
|
||||
@@ -241,7 +270,7 @@ describe('Places Module', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('togglePlace', () => {
|
||||
describe('addPlace', () => {
|
||||
it('adds a place reference when not present', async () => {
|
||||
const now = '2023-01-03T00:00:00.000Z';
|
||||
vi.setSystemTime(new Date(now));
|
||||
@@ -253,7 +282,7 @@ describe('Places Module', () => {
|
||||
};
|
||||
mockClient.getObject.mockResolvedValue(list);
|
||||
|
||||
await lists.togglePlace('hiking', 'place-123', 'w1q7');
|
||||
await lists.addPlace('hiking', 'place-123', 'w1q7');
|
||||
|
||||
expect(mockClient.storeObject).toHaveBeenCalledWith(
|
||||
'list',
|
||||
@@ -267,6 +296,21 @@ describe('Places Module', () => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('does nothing if place is already present', async () => {
|
||||
const list = {
|
||||
id: 'hiking',
|
||||
placeRefs: [{ id: 'place-123', geohash: 'w1q7' }],
|
||||
updatedAt: 'old-date',
|
||||
};
|
||||
mockClient.getObject.mockResolvedValue(list);
|
||||
|
||||
await lists.addPlace('hiking', 'place-123', 'w1q7');
|
||||
|
||||
expect(mockClient.storeObject).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('removePlace', () => {
|
||||
it('removes a place reference when present', async () => {
|
||||
const now = '2023-01-04T00:00:00.000Z';
|
||||
vi.setSystemTime(new Date(now));
|
||||
@@ -278,7 +322,7 @@ describe('Places Module', () => {
|
||||
};
|
||||
mockClient.getObject.mockResolvedValue(list);
|
||||
|
||||
await lists.togglePlace('hiking', 'place-123', 'w1q7');
|
||||
await lists.removePlace('hiking', 'place-123');
|
||||
|
||||
expect(mockClient.storeObject).toHaveBeenCalledWith(
|
||||
'list',
|
||||
@@ -291,35 +335,80 @@ describe('Places Module', () => {
|
||||
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it('does nothing if place is not present', async () => {
|
||||
const list = {
|
||||
id: 'hiking',
|
||||
placeRefs: [],
|
||||
updatedAt: 'old-date',
|
||||
};
|
||||
mockClient.getObject.mockResolvedValue(list);
|
||||
|
||||
await lists.removePlace('hiking', 'place-123');
|
||||
|
||||
expect(mockClient.storeObject).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('initDefaults', () => {
|
||||
it('creates default lists if they do not exist', async () => {
|
||||
// Mock getObject to return null for both
|
||||
it('creates "Want to go" list if missing', async () => {
|
||||
mockClient.getObject.mockResolvedValue(null);
|
||||
|
||||
await lists.initDefaults();
|
||||
|
||||
// Should check and create "to-go"
|
||||
expect(mockClient.getObject).toHaveBeenCalledWith('_lists/to-go');
|
||||
expect(mockClient.storeObject).toHaveBeenCalledWith(
|
||||
'list',
|
||||
'_lists/to-go',
|
||||
expect.objectContaining({
|
||||
title: 'Want to go',
|
||||
id: 'to-go',
|
||||
color: '#ff00ff',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('creates "To do" list if missing', async () => {
|
||||
mockClient.getObject.mockResolvedValue(null);
|
||||
|
||||
await lists.initDefaults();
|
||||
|
||||
// Should check and create "to-do"
|
||||
expect(mockClient.getObject).toHaveBeenCalledWith('_lists/to-do');
|
||||
expect(mockClient.storeObject).toHaveBeenCalledWith(
|
||||
'list',
|
||||
'_lists/to-do',
|
||||
expect.objectContaining({
|
||||
title: 'To do',
|
||||
id: 'to-do',
|
||||
color: '#008000',
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('does not overwrite existing lists', async () => {
|
||||
// Mock that "to-go" exists but "to-do" does not
|
||||
mockClient.getObject.mockImplementation(async (path: string) => {
|
||||
if (path === '_lists/to-go')
|
||||
return { id: 'to-go', title: 'Existing' };
|
||||
return null;
|
||||
});
|
||||
|
||||
await lists.initDefaults();
|
||||
|
||||
// Should NOT write to-go
|
||||
expect(mockClient.storeObject).not.toHaveBeenCalledWith(
|
||||
'list',
|
||||
'_lists/to-go',
|
||||
expect.anything()
|
||||
);
|
||||
|
||||
// Should write to-do
|
||||
expect(mockClient.storeObject).toHaveBeenCalledWith(
|
||||
'list',
|
||||
'_lists/to-do',
|
||||
expect.anything()
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user