Skip to content

Commit

Permalink
feat: Include parent containers in POST and DELETE changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
RubenVerborgh committed Nov 20, 2020
1 parent 0099d1d commit d879936
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 24 deletions.
13 changes: 13 additions & 0 deletions src/storage/MonitoringStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Patch } from '../ldp/http/Patch';
import type { Representation } from '../ldp/representation/Representation';
import type { RepresentationPreferences } from '../ldp/representation/RepresentationPreferences';
import type { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import { getParentContainer } from '../util/PathUtil';
import type { Conditions } from './Conditions';
import type { ResourceStore } from './ResourceStore';

Expand All @@ -22,12 +23,24 @@ export class MonitoringStore<T extends ResourceStore = ResourceStore>
public async addResource(container: ResourceIdentifier, representation: Representation,
conditions?: Conditions): Promise<ResourceIdentifier> {
const identifier = await this.source.addResource(container, representation, conditions);

// Both the container contents and the resource itself have changed
this.emit('changed', container);
this.emit('changed', identifier);

return identifier;
}

public async deleteResource(identifier: ResourceIdentifier, conditions?: Conditions): Promise<void> {
await this.source.deleteResource(identifier, conditions);

// Both the container contents and the resource itself have changed
try {
const container = getParentContainer(identifier);
this.emit('changed', container);
} catch {
// Parent container not found
}
this.emit('changed', identifier);
}

Expand Down
62 changes: 38 additions & 24 deletions test/unit/storage/MonitoringStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ describe('A MonitoringStore', (): void => {

beforeEach(async(): Promise<void> => {
source = {
getRepresentation: jest.fn(async(): Promise<any> => 'get'),
addResource: jest.fn(async(): Promise<any> => ({ path: 'newResource' })),
getRepresentation: jest.fn(async(): Promise<any> => ({ success: true })),
addResource: jest.fn(async(): Promise<any> => ({ path: 'http://example.org/foo/bar/new' })),
setRepresentation: jest.fn(async(): Promise<any> => undefined),
deleteResource: jest.fn(async(): Promise<any> => undefined),
modifyResource: jest.fn(async(): Promise<any> => undefined),
Expand All @@ -26,69 +26,83 @@ describe('A MonitoringStore', (): void => {
});

it('calls getRepresentation directly from the source.', async(): Promise<void> => {
await expect(store.getRepresentation({ path: 'getPath' }, {})).resolves.toBe('get');
await expect(store.getRepresentation({ path: 'getPath' }, {})).resolves.toEqual({ success: true });
expect(source.getRepresentation).toHaveBeenCalledTimes(1);
expect(source.getRepresentation).toHaveBeenLastCalledWith({ path: 'getPath' }, {}, undefined);
});

it('does not fire a change event after completing getRepresentation.', async(): Promise<void> => {
expect(changedCallback).toHaveBeenCalledTimes(0);
await store.getRepresentation({ path: 'getPath' }, {});
await store.getRepresentation({ path: 'http://example.org/foo/bar' }, {});
expect(changedCallback).toHaveBeenCalledTimes(0);
});

it('calls addResource directly from the source.', async(): Promise<void> => {
await expect(store.addResource({ path: 'addPath' }, {} as Representation)).resolves
.toStrictEqual({ path: 'newResource' });
await expect(store.addResource({ path: 'http://example.org/foo/bar' }, {} as Representation)).resolves
.toStrictEqual({ path: 'http://example.org/foo/bar/new' });
expect(source.addResource).toHaveBeenCalledTimes(1);
expect(source.addResource).toHaveBeenLastCalledWith({ path: 'addPath' }, {}, undefined);
expect(source.addResource).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, {}, undefined);
});

it('fires a change event after completing addResource.', async(): Promise<void> => {
const result = store.addResource({ path: 'addPath' }, {} as Representation);
it('fires resource and container change events after completing addResource.', async(): Promise<void> => {
const result = store.addResource({ path: 'http://example.org/foo/bar' }, {} as Representation);
expect(changedCallback).toHaveBeenCalledTimes(0);
await result;
expect(changedCallback).toHaveBeenCalledTimes(1);
expect(changedCallback).toHaveBeenCalledWith({ path: 'newResource' });
expect(changedCallback).toHaveBeenCalledTimes(2);
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' });
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar/new' });
});

it('calls setRepresentation directly from the source.', async(): Promise<void> => {
await expect(store.setRepresentation({ path: 'setPath' }, {} as Representation)).resolves.toBeUndefined();
await expect(store.setRepresentation({ path: 'http://example.org/foo/bar' }, {} as Representation))
.resolves.toBeUndefined();
expect(source.setRepresentation).toHaveBeenCalledTimes(1);
expect(source.setRepresentation).toHaveBeenLastCalledWith({ path: 'setPath' }, {}, undefined);
expect(source.setRepresentation).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, {}, undefined);
});

it('fires a change event after completing setRepresentation.', async(): Promise<void> => {
const result = store.setRepresentation({ path: 'setPath' }, {} as Representation);
it('fires a resource change event after completing setRepresentation.', async(): Promise<void> => {
const result = store.setRepresentation({ path: 'http://example.org/foo/bar' }, {} as Representation);
expect(changedCallback).toHaveBeenCalledTimes(0);
await result;
expect(changedCallback).toHaveBeenCalledTimes(1);
expect(changedCallback).toHaveBeenCalledWith({ path: 'setPath' });
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' });
});

it('calls deleteResource directly from the source.', async(): Promise<void> => {
await expect(store.deleteResource({ path: 'deletePath' })).resolves.toBeUndefined();
await expect(store.deleteResource({ path: 'http://example.org/foo/bar' })).resolves.toBeUndefined();
expect(source.deleteResource).toHaveBeenCalledTimes(1);
expect(source.deleteResource).toHaveBeenLastCalledWith({ path: 'deletePath' }, undefined);
expect(source.deleteResource).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, undefined);
});

it('fires resource and container change events after completing deleteResource.', async(): Promise<void> => {
const result = store.deleteResource({ path: 'http://example.org/foo/bar' });
expect(changedCallback).toHaveBeenCalledTimes(0);
await result;
expect(changedCallback).toHaveBeenCalledTimes(2);
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/' });
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' });
});

it('fires a change event after completing deleteResource.', async(): Promise<void> => {
const result = store.deleteResource({ path: 'deletePath' });
it('fires a resource change event after completing deleteResource on the root.', async(): Promise<void> => {
const result = store.deleteResource({ path: 'http://example.org/' });
expect(changedCallback).toHaveBeenCalledTimes(0);
await result;
expect(changedCallback).toHaveBeenCalledTimes(1);
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/' });
});

it('calls modifyResource directly from the source.', async(): Promise<void> => {
await expect(store.modifyResource({ path: 'modifyPath' }, {} as Patch)).resolves.toBeUndefined();
await expect(store.modifyResource({ path: 'http://example.org/foo/bar' }, {} as Patch))
.resolves.toBeUndefined();
expect(source.modifyResource).toHaveBeenCalledTimes(1);
expect(source.modifyResource).toHaveBeenLastCalledWith({ path: 'modifyPath' }, {}, undefined);
expect(source.modifyResource).toHaveBeenLastCalledWith({ path: 'http://example.org/foo/bar' }, {}, undefined);
});

it('fires a change event after completing modifyResource.', async(): Promise<void> => {
const result = store.modifyResource({ path: 'modifyPath' }, {} as Patch);
it('fires a resource change event after completing modifyResource.', async(): Promise<void> => {
const result = store.modifyResource({ path: 'http://example.org/foo/bar' }, {} as Patch);
expect(changedCallback).toHaveBeenCalledTimes(0);
await result;
expect(changedCallback).toHaveBeenCalledTimes(1);
expect(changedCallback).toHaveBeenCalledWith({ path: 'http://example.org/foo/bar' });
});
});

0 comments on commit d879936

Please sign in to comment.