mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Stop creating meta files for each new resource #1217
This commit is contained in:
committed by
Joachim Van Herwegen
parent
f0f900edfb
commit
fbbccb0cf1
@@ -2,6 +2,7 @@ import { promises as fsPromises } from 'fs';
|
||||
import type { Stats } from 'fs';
|
||||
import fetch from 'cross-fetch';
|
||||
import type { Response } from 'cross-fetch';
|
||||
import { pathExists } from 'fs-extra';
|
||||
import { joinFilePath, joinUrl } from '../../src';
|
||||
import type { App } from '../../src';
|
||||
import { getPort } from '../util/Util';
|
||||
@@ -151,6 +152,18 @@ describe('A quota server', (): void => {
|
||||
await expect(response2).resolves.toBeDefined();
|
||||
expect((await response2).status).toBe(413);
|
||||
});
|
||||
|
||||
it('should not generate metadata files (the only possible entry content-length is removed after quota validation).',
|
||||
async(): Promise<void> => {
|
||||
const testFile3 = `${pod1}/test3.txt`;
|
||||
const response1 = performSimplePutWithLength(testFile3, 100);
|
||||
await expect(response1).resolves.toBeDefined();
|
||||
expect((await response1).status).toBe(201);
|
||||
|
||||
// Validate that a meta file was not created
|
||||
const check = await pathExists(`${rootFilePath}/${podName1}/test3.txt.meta`);
|
||||
expect(check).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
/** Test the general functionality of the server using global quota */
|
||||
@@ -218,5 +231,17 @@ describe('A quota server', (): void => {
|
||||
const awaitedRes2 = await response2;
|
||||
expect(awaitedRes2.status).toBe(413);
|
||||
});
|
||||
|
||||
it('should not generate metadata files (the only possible entry content-length is removed after quota validation).',
|
||||
async(): Promise<void> => {
|
||||
const testFile3 = `${pod1}/test5.txt`;
|
||||
const response1 = performSimplePutWithLength(testFile3, 100);
|
||||
await expect(response1).resolves.toBeDefined();
|
||||
expect((await response1).status).toBe(201);
|
||||
|
||||
// Validate that a meta file was not created
|
||||
const check = await pathExists(`${rootFilePath}/${podName1}/test5.txt.meta`);
|
||||
expect(check).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
120
test/unit/storage/accessors/FilterMetadataDataAccessor.test.ts
Normal file
120
test/unit/storage/accessors/FilterMetadataDataAccessor.test.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { APPLICATION_JSON, CONTENT_LENGTH, CONTENT_TYPE, FilterPattern, toNamedTerm } from '../../../../src';
|
||||
import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata';
|
||||
import type { DataAccessor } from '../../../../src/storage/accessors/DataAccessor';
|
||||
import { FilterMetadataDataAccessor } from '../../../../src/storage/accessors/FilterMetadataDataAccessor';
|
||||
import { guardedStreamFrom } from '../../../../src/util/StreamUtil';
|
||||
|
||||
describe('FilterMetadataDataAccessor', (): void => {
|
||||
let childAccessor: jest.Mocked<DataAccessor>;
|
||||
|
||||
const mockIdentifier = { path: 'http://localhost/test.txt' };
|
||||
const mockData = guardedStreamFrom('test string');
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
jest.clearAllMocks();
|
||||
childAccessor = {
|
||||
writeDocument: jest.fn(),
|
||||
writeContainer: jest.fn(),
|
||||
} as any;
|
||||
childAccessor.getChildren = jest.fn();
|
||||
});
|
||||
|
||||
it('removes only the matching metadata properties when calling writeDocument.', async(): Promise<void> => {
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor,
|
||||
[ new FilterPattern(undefined, CONTENT_LENGTH) ]);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.contentLength = 40;
|
||||
mockMetadata.contentType = APPLICATION_JSON;
|
||||
await filterMetadataAccessor.writeDocument(mockIdentifier, mockData, mockMetadata);
|
||||
expect(childAccessor.writeDocument).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeDocument).toHaveBeenLastCalledWith(mockIdentifier, mockData, mockMetadata);
|
||||
expect(mockMetadata.contentLength).toBeUndefined();
|
||||
expect(mockMetadata.contentType).toBe(APPLICATION_JSON);
|
||||
});
|
||||
|
||||
it('supports multiple filter patterns when calling writeDocument.', async(): Promise<void> => {
|
||||
const filters = [
|
||||
new FilterPattern(undefined, CONTENT_LENGTH),
|
||||
new FilterPattern(undefined, CONTENT_TYPE),
|
||||
];
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor, filters);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.contentLength = 40;
|
||||
mockMetadata.contentType = APPLICATION_JSON;
|
||||
await filterMetadataAccessor.writeDocument(mockIdentifier, mockData, mockMetadata);
|
||||
expect(childAccessor.writeDocument).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeDocument).toHaveBeenLastCalledWith(mockIdentifier, mockData, mockMetadata);
|
||||
expect(mockMetadata.contentLength).toBeUndefined();
|
||||
expect(mockMetadata.contentType).toBeUndefined();
|
||||
});
|
||||
|
||||
it('removes only the matching metadata properties when calling writeContainer.', async(): Promise<void> => {
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor,
|
||||
[ new FilterPattern(undefined, CONTENT_LENGTH) ]);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.contentLength = 40;
|
||||
mockMetadata.contentType = APPLICATION_JSON;
|
||||
await filterMetadataAccessor.writeContainer(mockIdentifier, mockMetadata);
|
||||
expect(childAccessor.writeContainer).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeContainer).toHaveBeenLastCalledWith(mockIdentifier, mockMetadata);
|
||||
expect(mockMetadata.contentLength).toBeUndefined();
|
||||
expect(mockMetadata.contentType).toBe(APPLICATION_JSON);
|
||||
});
|
||||
|
||||
it('supports multiple filter patterns when calling writeContainer.', async(): Promise<void> => {
|
||||
const filters = [
|
||||
new FilterPattern(undefined, CONTENT_LENGTH),
|
||||
new FilterPattern(undefined, CONTENT_TYPE),
|
||||
];
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor, filters);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.contentLength = 40;
|
||||
mockMetadata.contentType = APPLICATION_JSON;
|
||||
await filterMetadataAccessor.writeContainer(mockIdentifier, mockMetadata);
|
||||
expect(childAccessor.writeContainer).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeContainer).toHaveBeenLastCalledWith(mockIdentifier, mockMetadata);
|
||||
expect(mockMetadata.contentLength).toBeUndefined();
|
||||
expect(mockMetadata.contentType).toBeUndefined();
|
||||
});
|
||||
|
||||
it('an empty filter matches all metadata entries, and thus everything is removed.', async(): Promise<void> => {
|
||||
const filters = [ new FilterPattern() ];
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor, filters);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.contentLength = 40;
|
||||
mockMetadata.contentType = APPLICATION_JSON;
|
||||
await filterMetadataAccessor.writeContainer(mockIdentifier, mockMetadata);
|
||||
expect(childAccessor.writeContainer).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeContainer).toHaveBeenLastCalledWith(mockIdentifier, mockMetadata);
|
||||
expect(mockMetadata.contentLength).toBeUndefined();
|
||||
expect(mockMetadata.contentType).toBeUndefined();
|
||||
expect(mockMetadata.quads()).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('supports filtering based on subject.', async(): Promise<void> => {
|
||||
const subject = 'http://example.org/resource/test1';
|
||||
const filters = [ new FilterPattern(subject) ];
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor, filters);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.addQuad(subject, toNamedTerm('http://xmlns.com/foaf/0.1/name'), 'Alice');
|
||||
expect(mockMetadata.quads(subject)).toHaveLength(1);
|
||||
await filterMetadataAccessor.writeDocument(mockIdentifier, mockData, mockMetadata);
|
||||
expect(childAccessor.writeDocument).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeDocument).toHaveBeenLastCalledWith(mockIdentifier, mockData, mockMetadata);
|
||||
expect(mockMetadata.quads(subject)).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('supports filtering based on object.', async(): Promise<void> => {
|
||||
const subject = 'http://example.org/resource/test1';
|
||||
const object = 'http://example.org/resource/test2';
|
||||
const filters = [ new FilterPattern(undefined, undefined, object) ];
|
||||
const filterMetadataAccessor = new FilterMetadataDataAccessor(childAccessor, filters);
|
||||
const mockMetadata = new RepresentationMetadata();
|
||||
mockMetadata.addQuad(subject, toNamedTerm('http://xmlns.com/foaf/0.1/knows'), toNamedTerm(object));
|
||||
expect(mockMetadata.quads(subject)).toHaveLength(1);
|
||||
await filterMetadataAccessor.writeContainer(mockIdentifier, mockMetadata);
|
||||
expect(childAccessor.writeContainer).toHaveBeenCalledTimes(1);
|
||||
expect(childAccessor.writeContainer).toHaveBeenLastCalledWith(mockIdentifier, mockMetadata);
|
||||
expect(mockMetadata.quads(subject)).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user