diff --git a/src/storage/accessors/SparqlDataAccessor.ts b/src/storage/accessors/SparqlDataAccessor.ts index 56970bfb1..c67e1a3a3 100644 --- a/src/storage/accessors/SparqlDataAccessor.ts +++ b/src/storage/accessors/SparqlDataAccessor.ts @@ -238,7 +238,9 @@ export class SparqlDataAccessor implements DataAccessor { if (triples) { // This needs to be first so it happens before the insert updates.unshift(this.sparqlUpdateDeleteAll(name)); - insert.push(this.sparqlUpdateGraph(name, triples)); + if (triples.length > 0) { + insert.push(this.sparqlUpdateGraph(name, triples)); + } } return { diff --git a/test/unit/storage/accessors/SparqlDataAccessor.test.ts b/test/unit/storage/accessors/SparqlDataAccessor.test.ts index f42f7de37..8c7e7e029 100644 --- a/test/unit/storage/accessors/SparqlDataAccessor.test.ts +++ b/test/unit/storage/accessors/SparqlDataAccessor.test.ts @@ -190,6 +190,25 @@ describe('A SparqlDataAccessor', (): void => { ])); }); + it('overwrites the data and metadata when writing an empty resource.', async(): Promise => { + metadata = new RepresentationMetadata('http://test.com/container/resource', + { [RDF.type]: [ toNamedNode(LDP.Resource) ]}); + const empty = guardedStreamFrom([]); + await expect(accessor.writeDocument({ path: 'http://test.com/container/resource' }, empty, metadata)) + .resolves.toBeUndefined(); + + expect(fetchUpdate).toHaveBeenCalledTimes(1); + expect(fetchUpdate.mock.calls[0][0]).toBe(endpoint); + expect(simplifyQuery(fetchUpdate.mock.calls[0][1])).toBe(simplifyQuery([ + 'DELETE WHERE { GRAPH { ?s ?p ?o. } };', + 'DELETE WHERE { GRAPH { ?s ?p ?o. } };', + 'INSERT DATA {', + ' GRAPH { . }', + ' GRAPH { . }', + '}', + ])); + }); + it('removes all references when deleting a resource.', async(): Promise => { metadata = new RepresentationMetadata('http://test.com/container/', { [RDF.type]: [ toNamedNode(LDP.Resource), toNamedNode(LDP.Container) ]});