summaryrefslogtreecommitdiff
path: root/packages/backend/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'packages/backend/test/unit')
-rw-r--r--packages/backend/test/unit/DriveService.ts2
-rw-r--r--packages/backend/test/unit/FetchInstanceMetadataService.ts109
-rw-r--r--packages/backend/test/unit/FileInfoService.ts22
-rw-r--r--packages/backend/test/unit/RelayService.ts8
-rw-r--r--packages/backend/test/unit/RoleService.ts30
-rw-r--r--packages/backend/test/unit/activitypub.ts248
-rw-r--r--packages/backend/test/unit/chart.ts12
7 files changed, 378 insertions, 53 deletions
diff --git a/packages/backend/test/unit/DriveService.ts b/packages/backend/test/unit/DriveService.ts
index 4065665579..9ee6d4bcfb 100644
--- a/packages/backend/test/unit/DriveService.ts
+++ b/packages/backend/test/unit/DriveService.ts
@@ -34,7 +34,7 @@ describe('DriveService', () => {
test('delete a file', async () => {
s3Mock.on(DeleteObjectCommand)
.resolves({} as DeleteObjectCommandOutput);
-
+
await driveService.deleteObjectStorageFile('peace of the world');
});
diff --git a/packages/backend/test/unit/FetchInstanceMetadataService.ts b/packages/backend/test/unit/FetchInstanceMetadataService.ts
new file mode 100644
index 0000000000..1ee2939829
--- /dev/null
+++ b/packages/backend/test/unit/FetchInstanceMetadataService.ts
@@ -0,0 +1,109 @@
+process.env.NODE_ENV = 'test';
+
+import { jest } from '@jest/globals';
+import { ModuleMocker } from 'jest-mock';
+import { Test } from '@nestjs/testing';
+import { GlobalModule } from '@/GlobalModule.js';
+import { FetchInstanceMetadataService } from '@/core/FetchInstanceMetadataService.js';
+import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
+import { HttpRequestService } from '@/core/HttpRequestService.js';
+import { LoggerService } from '@/core/LoggerService.js';
+import { UtilityService } from '@/core/UtilityService.js';
+import { IdService } from '@/core/IdService.js';
+import { DI } from '@/di-symbols.js';
+import type { TestingModule } from '@nestjs/testing';
+import type { MockFunctionMetadata } from 'jest-mock';
+import { Redis } from 'ioredis'
+
+function mockRedis() {
+ const hash = {};
+ const set = jest.fn((key, value) => {
+ const ret = hash[key];
+ hash[key] = value;
+ return ret;
+ });
+ return set;
+}
+
+describe('FetchInstanceMetadataService', () => {
+ let app: TestingModule;
+ let fetchInstanceMetadataService: jest.Mocked<FetchInstanceMetadataService>;
+ let federatedInstanceService: jest.Mocked<FederatedInstanceService>;
+ let httpRequestService: jest.Mocked<HttpRequestService>;
+ let redisClient: jest.Mocked<Redis.Redis>;
+
+ beforeAll(async () => {
+ app = await Test
+ .createTestingModule({
+ imports: [
+ GlobalModule,
+ ],
+ providers: [
+ FetchInstanceMetadataService,
+ LoggerService,
+ UtilityService,
+ IdService,
+ ],
+ })
+ .useMocker((token) => {
+ if (token === HttpRequestService) {
+ return { getJson: jest.fn(), getHtml: jest.fn(), send: jest.fn(), };
+ } else if (token === FederatedInstanceService) {
+ return { fetch: jest.fn() };
+ } else if (token === DI.redis) {
+ return mockRedis;
+ }})
+ .compile();
+
+ app.enableShutdownHooks();
+
+ fetchInstanceMetadataService = app.get<FetchInstanceMetadataService>(FetchInstanceMetadataService);
+ federatedInstanceService = app.get<FederatedInstanceService>(FederatedInstanceService) as jest.Mocked<FederatedInstanceService>;
+ redisClient = app.get<Redis.Redis>(DI.redis) as jest.Mocked<Redis.Redis>;
+ httpRequestService = app.get<HttpRequestService>(HttpRequestService) as jest.Mocked<HttpRequestService>;
+ });
+
+ afterAll(async () => {
+ await app.close();
+ });
+
+ test('Lock and update', async () => {
+ redisClient.set = mockRedis();
+ const now = Date.now();
+ federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => { return now - 10 * 1000 * 60 * 60 * 24; } } });
+ httpRequestService.getJson.mockImplementation(() => { throw Error(); });
+ const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
+ const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: "example.com" });
+ expect(tryLockSpy).toHaveBeenCalledTimes(1);
+ expect(unlockSpy).toHaveBeenCalledTimes(1);
+ expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
+ expect(httpRequestService.getJson).toHaveBeenCalled();
+ });
+ test("Lock and don't update", async () => {
+ redisClient.set = mockRedis();
+ const now = Date.now();
+ federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => now } });
+ httpRequestService.getJson.mockImplementation(() => { throw Error(); });
+ const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
+ const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: "example.com" });
+ expect(tryLockSpy).toHaveBeenCalledTimes(1);
+ expect(unlockSpy).toHaveBeenCalledTimes(1);
+ expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(1);
+ expect(httpRequestService.getJson).toHaveBeenCalledTimes(0);
+ });
+ test('Do nothing when lock not acquired', async () => {
+ redisClient.set = mockRedis();
+ federatedInstanceService.fetch.mockReturnValue({ infoUpdatedAt: { getTime: () => now - 10 * 1000 * 60 * 60 * 24 } });
+ httpRequestService.getJson.mockImplementation(() => { throw Error(); });
+ const tryLockSpy = jest.spyOn(fetchInstanceMetadataService, 'tryLock');
+ const unlockSpy = jest.spyOn(fetchInstanceMetadataService, 'unlock');
+ await fetchInstanceMetadataService.tryLock("example.com");
+ await fetchInstanceMetadataService.fetchInstanceMetadata({ host: "example.com" });
+ expect(tryLockSpy).toHaveBeenCalledTimes(2);
+ expect(unlockSpy).toHaveBeenCalledTimes(0);
+ expect(federatedInstanceService.fetch).toHaveBeenCalledTimes(0);
+ expect(httpRequestService.getJson).toHaveBeenCalledTimes(0);
+ });
+});
diff --git a/packages/backend/test/unit/FileInfoService.ts b/packages/backend/test/unit/FileInfoService.ts
index f378184c74..efb9bdacc3 100644
--- a/packages/backend/test/unit/FileInfoService.ts
+++ b/packages/backend/test/unit/FileInfoService.ts
@@ -94,7 +94,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('Generic APNG', async () => {
const path = `${resources}/anime.png`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -114,7 +114,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('Generic AGIF', async () => {
const path = `${resources}/anime.gif`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -134,7 +134,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('PNG with alpha', async () => {
const path = `${resources}/with-alpha.png`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -154,7 +154,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('Generic SVG', async () => {
const path = `${resources}/image.svg`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -174,7 +174,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('SVG with XML definition', async () => {
// https://github.com/misskey-dev/misskey/issues/4413
const path = `${resources}/with-xml-def.svg`;
@@ -195,7 +195,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('Dimension limit', async () => {
const path = `${resources}/25000x25000.png`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -215,7 +215,7 @@ describe('FileInfoService', () => {
orientation: undefined,
});
});
-
+
test('Rotate JPEG', async () => {
const path = `${resources}/rotate.jpg`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -257,7 +257,7 @@ describe('FileInfoService', () => {
},
});
});
-
+
test('WAV', async () => {
const path = `${resources}/kick_gaba7.wav`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -277,7 +277,7 @@ describe('FileInfoService', () => {
},
});
});
-
+
test('AAC', async () => {
const path = `${resources}/kick_gaba7.aac`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -297,7 +297,7 @@ describe('FileInfoService', () => {
},
});
});
-
+
test('FLAC', async () => {
const path = `${resources}/kick_gaba7.flac`;
const info = await fileInfoService.getFileInfo(path, { skipSensitiveDetection: true }) as any;
@@ -317,7 +317,7 @@ describe('FileInfoService', () => {
},
});
});
-
+
/*
* video/webmとして検出されてしまう
test('WEBM AUDIO', async () => {
diff --git a/packages/backend/test/unit/RelayService.ts b/packages/backend/test/unit/RelayService.ts
index c2280142a6..6bf08f5091 100644
--- a/packages/backend/test/unit/RelayService.ts
+++ b/packages/backend/test/unit/RelayService.ts
@@ -61,7 +61,7 @@ describe('RelayService', () => {
await app.close();
});
- test('addRelay', async () => {
+ test('addRelay', async () => {
const result = await relayService.addRelay('https://example.com');
expect(result.inbox).toBe('https://example.com');
@@ -72,7 +72,7 @@ describe('RelayService', () => {
//expect(queueService.deliver.mock.lastCall![0].username).toBe('relay.actor');
});
- test('listRelay', async () => {
+ test('listRelay', async () => {
const result = await relayService.listRelay();
expect(result.length).toBe(1);
@@ -80,7 +80,7 @@ describe('RelayService', () => {
expect(result[0].status).toBe('requesting');
});
- test('removeRelay: succ', async () => {
+ test('removeRelay: succ', async () => {
await relayService.removeRelay('https://example.com');
expect(queueService.deliver).toHaveBeenCalled();
@@ -93,7 +93,7 @@ describe('RelayService', () => {
expect(list.length).toBe(0);
});
- test('removeRelay: fail', async () => {
+ test('removeRelay: fail', async () => {
await expect(relayService.removeRelay('https://x.example.com'))
.rejects.toThrow('relay not found');
});
diff --git a/packages/backend/test/unit/RoleService.ts b/packages/backend/test/unit/RoleService.ts
index 907f1f2edc..6979f23e0c 100644
--- a/packages/backend/test/unit/RoleService.ts
+++ b/packages/backend/test/unit/RoleService.ts
@@ -4,7 +4,6 @@ import { jest } from '@jest/globals';
import { ModuleMocker } from 'jest-mock';
import { Test } from '@nestjs/testing';
import * as lolex from '@sinonjs/fake-timers';
-import rndstr from 'rndstr';
import { GlobalModule } from '@/GlobalModule.js';
import { RoleService } from '@/core/RoleService.js';
import type { Role, RolesRepository, RoleAssignmentsRepository, UsersRepository, User } from '@/models/index.js';
@@ -14,6 +13,7 @@ import { genAid } from '@/misc/id/aid.js';
import { CacheService } from '@/core/CacheService.js';
import { IdService } from '@/core/IdService.js';
import { GlobalEventService } from '@/core/GlobalEventService.js';
+import { secureRndstr } from '@/misc/secure-rndstr.js';
import { sleep } from '../utils.js';
import type { TestingModule } from '@nestjs/testing';
import type { MockFunctionMetadata } from 'jest-mock';
@@ -30,7 +30,7 @@ describe('RoleService', () => {
let clock: lolex.InstalledClock;
function createUser(data: Partial<User> = {}) {
- const un = rndstr('a-z0-9', 16);
+ const un = secureRndstr(16);
return usersRepository.insert({
id: genAid(new Date()),
createdAt: new Date(),
@@ -106,19 +106,19 @@ describe('RoleService', () => {
});
describe('getUserPolicies', () => {
- test('instance default policies', async () => {
+ test('instance default policies', async () => {
const user = await createUser();
metaService.fetch.mockResolvedValue({
policies: {
canManageCustomEmojis: false,
},
} as any);
-
+
const result = await roleService.getUserPolicies(user.id);
-
+
expect(result.canManageCustomEmojis).toBe(false);
});
-
+
test('instance default policies 2', async () => {
const user = await createUser();
metaService.fetch.mockResolvedValue({
@@ -126,12 +126,12 @@ describe('RoleService', () => {
canManageCustomEmojis: true,
},
} as any);
-
+
const result = await roleService.getUserPolicies(user.id);
-
+
expect(result.canManageCustomEmojis).toBe(true);
});
-
+
test('with role', async () => {
const user = await createUser();
const role = await createRole({
@@ -150,9 +150,9 @@ describe('RoleService', () => {
canManageCustomEmojis: false,
},
} as any);
-
+
const result = await roleService.getUserPolicies(user.id);
-
+
expect(result.canManageCustomEmojis).toBe(true);
});
@@ -185,9 +185,9 @@ describe('RoleService', () => {
driveCapacityMb: 50,
},
} as any);
-
+
const result = await roleService.getUserPolicies(user.id);
-
+
expect(result.driveCapacityMb).toBe(100);
});
@@ -226,7 +226,7 @@ describe('RoleService', () => {
canManageCustomEmojis: false,
},
} as any);
-
+
const user1Policies = await roleService.getUserPolicies(user1.id);
const user2Policies = await roleService.getUserPolicies(user2.id);
expect(user1Policies.canManageCustomEmojis).toBe(false);
@@ -251,7 +251,7 @@ describe('RoleService', () => {
canManageCustomEmojis: false,
},
} as any);
-
+
const result = await roleService.getUserPolicies(user.id);
expect(result.canManageCustomEmojis).toBe(true);
diff --git a/packages/backend/test/unit/activitypub.ts b/packages/backend/test/unit/activitypub.ts
index 146998937e..78b916c112 100644
--- a/packages/backend/test/unit/activitypub.ts
+++ b/packages/backend/test/unit/activitypub.ts
@@ -1,10 +1,10 @@
process.env.NODE_ENV = 'test';
import * as assert from 'assert';
-import rndstr from 'rndstr';
import { Test } from '@nestjs/testing';
import { jest } from '@jest/globals';
+import { ApImageService } from '@/core/activitypub/models/ApImageService.js';
import { ApNoteService } from '@/core/activitypub/models/ApNoteService.js';
import { ApPersonService } from '@/core/activitypub/models/ApPersonService.js';
import { ApRendererService } from '@/core/activitypub/ApRendererService.js';
@@ -12,15 +12,22 @@ import { GlobalModule } from '@/GlobalModule.js';
import { CoreModule } from '@/core/CoreModule.js';
import { FederatedInstanceService } from '@/core/FederatedInstanceService.js';
import { LoggerService } from '@/core/LoggerService.js';
-import type { IActor } from '@/core/activitypub/type.js';
+import type { IActor, IApDocument, ICollection, IPost } from '@/core/activitypub/type.js';
+import { Meta, Note } from '@/models/index.js';
+import { secureRndstr } from '@/misc/secure-rndstr.js';
+import { DownloadService } from '@/core/DownloadService.js';
+import { MetaService } from '@/core/MetaService.js';
+import type { RemoteUser } from '@/models/entities/User.js';
import { MockResolver } from '../misc/mock-resolver.js';
-import { Note } from '@/models/index.js';
const host = 'https://host1.test';
-function createRandomActor(): IActor & { id: string } {
- const preferredUsername = `${rndstr('A-Z', 4)}${rndstr('a-z', 4)}`;
- const actorId = `${host}/users/${preferredUsername.toLowerCase()}`;
+type NonTransientIActor = IActor & { id: string };
+type NonTransientIPost = IPost & { id: string };
+
+function createRandomActor({ actorHost = host } = {}): NonTransientIActor {
+ const preferredUsername = secureRndstr(8);
+ const actorId = `${actorHost}/users/${preferredUsername.toLowerCase()}`;
return {
'@context': 'https://www.w3.org/ns/activitystreams',
@@ -32,16 +39,75 @@ function createRandomActor(): IActor & { id: string } {
};
}
+function createRandomNote(actor: NonTransientIActor): NonTransientIPost {
+ const id = secureRndstr(8);
+ const noteId = `${new URL(actor.id).origin}/notes/${id}`;
+
+ return {
+ id: noteId,
+ type: 'Note',
+ attributedTo: actor.id,
+ content: 'test test foo',
+ };
+}
+
+function createRandomNotes(actor: NonTransientIActor, length: number): NonTransientIPost[] {
+ return new Array(length).fill(null).map(() => createRandomNote(actor));
+}
+
+function createRandomFeaturedCollection(actor: NonTransientIActor, length: number): ICollection {
+ const items = createRandomNotes(actor, length);
+
+ return {
+ '@context': 'https://www.w3.org/ns/activitystreams',
+ type: 'Collection',
+ id: actor.outbox as string,
+ totalItems: items.length,
+ items,
+ };
+}
+
+async function createRandomRemoteUser(
+ resolver: MockResolver,
+ personService: ApPersonService,
+): Promise<RemoteUser> {
+ const actor = createRandomActor();
+ resolver.register(actor.id, actor);
+
+ return await personService.createPerson(actor.id, resolver);
+}
+
describe('ActivityPub', () => {
+ let imageService: ApImageService;
let noteService: ApNoteService;
let personService: ApPersonService;
let rendererService: ApRendererService;
let resolver: MockResolver;
- beforeEach(async () => {
+ const metaInitial = {
+ cacheRemoteFiles: true,
+ cacheRemoteSensitiveFiles: true,
+ blockedHosts: [] as string[],
+ sensitiveWords: [] as string[],
+ } as Meta;
+ let meta = metaInitial;
+
+ beforeAll(async () => {
const app = await Test.createTestingModule({
imports: [GlobalModule, CoreModule],
- }).compile();
+ })
+ .overrideProvider(DownloadService).useValue({
+ async downloadUrl(): Promise<{ filename: string }> {
+ return {
+ filename: 'dummy.tmp',
+ };
+ },
+ })
+ .overrideProvider(MetaService).useValue({
+ async fetch(): Promise<Meta> {
+ return meta;
+ },
+ }).compile();
await app.init();
app.enableShutdownHooks();
@@ -49,11 +115,16 @@ describe('ActivityPub', () => {
noteService = app.get<ApNoteService>(ApNoteService);
personService = app.get<ApPersonService>(ApPersonService);
rendererService = app.get<ApRendererService>(ApRendererService);
+ imageService = app.get<ApImageService>(ApImageService);
resolver = new MockResolver(await app.resolve<LoggerService>(LoggerService));
// Prevent ApPersonService from fetching instance, as it causes Jest import-after-test error
const federatedInstanceService = app.get<FederatedInstanceService>(FederatedInstanceService);
- jest.spyOn(federatedInstanceService, 'fetch').mockImplementation(() => new Promise(() => {}));
+ jest.spyOn(federatedInstanceService, 'fetch').mockImplementation(() => new Promise(() => { }));
+ });
+
+ beforeEach(() => {
+ resolver.clear();
});
describe('Parse minimum object', () => {
@@ -61,7 +132,7 @@ describe('ActivityPub', () => {
const post = {
'@context': 'https://www.w3.org/ns/activitystreams',
- id: `${host}/users/${rndstr('0-9a-z', 8)}`,
+ id: `${host}/users/${secureRndstr(8)}`,
type: 'Note',
attributedTo: actor.id,
to: 'https://www.w3.org/ns/activitystreams#Public',
@@ -69,7 +140,7 @@ describe('ActivityPub', () => {
};
test('Minimum Actor', async () => {
- resolver._register(actor.id, actor);
+ resolver.register(actor.id, actor);
const user = await personService.createPerson(actor.id, resolver);
@@ -79,8 +150,8 @@ describe('ActivityPub', () => {
});
test('Minimum Note', async () => {
- resolver._register(actor.id, actor);
- resolver._register(post.id, post);
+ resolver.register(actor.id, actor);
+ resolver.register(post.id, post);
const note = await noteService.createNote(post.id, resolver, true);
@@ -94,10 +165,10 @@ describe('ActivityPub', () => {
test('Truncate long name', async () => {
const actor = {
...createRandomActor(),
- name: rndstr('0-9a-z', 129),
+ name: secureRndstr(129),
};
- resolver._register(actor.id, actor);
+ resolver.register(actor.id, actor);
const user = await personService.createPerson(actor.id, resolver);
@@ -110,7 +181,7 @@ describe('ActivityPub', () => {
name: '',
};
- resolver._register(actor.id, actor);
+ resolver.register(actor.id, actor);
const user = await personService.createPerson(actor.id, resolver);
@@ -126,4 +197,149 @@ describe('ActivityPub', () => {
} as Note);
});
});
+
+ describe('Featured', () => {
+ test('Fetch featured notes from IActor', async () => {
+ const actor = createRandomActor();
+ actor.featured = `${actor.id}/collections/featured`;
+
+ const featured = createRandomFeaturedCollection(actor, 5);
+
+ resolver.register(actor.id, actor);
+ resolver.register(actor.featured, featured);
+
+ await personService.createPerson(actor.id, resolver);
+
+ // All notes in `featured` are same-origin, no need to fetch notes again
+ assert.deepStrictEqual(resolver.remoteGetTrials(), [actor.id, actor.featured]);
+
+ // Created notes without resolving anything
+ for (const item of featured.items as IPost[]) {
+ const note = await noteService.fetchNote(item);
+ assert.ok(note);
+ assert.strictEqual(note.text, 'test test foo');
+ assert.strictEqual(note.uri, item.id);
+ }
+ });
+
+ test('Fetch featured notes from IActor pointing to another remote server', async () => {
+ const actor1 = createRandomActor();
+ actor1.featured = `${actor1.id}/collections/featured`;
+ const actor2 = createRandomActor({ actorHost: 'https://host2.test' });
+
+ const actor2Note = createRandomNote(actor2);
+ const featured = createRandomFeaturedCollection(actor1, 0);
+ (featured.items as IPost[]).push({
+ ...actor2Note,
+ content: 'test test bar', // fraud!
+ });
+
+ resolver.register(actor1.id, actor1);
+ resolver.register(actor1.featured, featured);
+ resolver.register(actor2.id, actor2);
+ resolver.register(actor2Note.id, actor2Note);
+
+ await personService.createPerson(actor1.id, resolver);
+
+ // actor2Note is from a different server and needs to be fetched again
+ assert.deepStrictEqual(
+ resolver.remoteGetTrials(),
+ [actor1.id, actor1.featured, actor2Note.id, actor2.id],
+ );
+
+ const note = await noteService.fetchNote(actor2Note.id);
+ assert.ok(note);
+
+ // Reflects the original content instead of the fraud
+ assert.strictEqual(note.text, 'test test foo');
+ assert.strictEqual(note.uri, actor2Note.id);
+ });
+ });
+
+ describe('Images', () => {
+ test('Create images', async () => {
+ const imageObject: IApDocument = {
+ type: 'Document',
+ mediaType: 'image/png',
+ url: 'http://host1.test/foo.png',
+ name: '',
+ };
+ const driveFile = await imageService.createImage(
+ await createRandomRemoteUser(resolver, personService),
+ imageObject,
+ );
+ assert.ok(!driveFile.isLink);
+
+ const sensitiveImageObject: IApDocument = {
+ type: 'Document',
+ mediaType: 'image/png',
+ url: 'http://host1.test/bar.png',
+ name: '',
+ sensitive: true,
+ };
+ const sensitiveDriveFile = await imageService.createImage(
+ await createRandomRemoteUser(resolver, personService),
+ sensitiveImageObject,
+ );
+ assert.ok(!sensitiveDriveFile.isLink);
+ });
+
+ test('cacheRemoteFiles=false disables caching', async () => {
+ meta = { ...metaInitial, cacheRemoteFiles: false };
+
+ const imageObject: IApDocument = {
+ type: 'Document',
+ mediaType: 'image/png',
+ url: 'http://host1.test/foo.png',
+ name: '',
+ };
+ const driveFile = await imageService.createImage(
+ await createRandomRemoteUser(resolver, personService),
+ imageObject,
+ );
+ assert.ok(driveFile.isLink);
+
+ const sensitiveImageObject: IApDocument = {
+ type: 'Document',
+ mediaType: 'image/png',
+ url: 'http://host1.test/bar.png',
+ name: '',
+ sensitive: true,
+ };
+ const sensitiveDriveFile = await imageService.createImage(
+ await createRandomRemoteUser(resolver, personService),
+ sensitiveImageObject,
+ );
+ assert.ok(sensitiveDriveFile.isLink);
+ });
+
+ test('cacheRemoteSensitiveFiles=false only affects sensitive files', async () => {
+ meta = { ...metaInitial, cacheRemoteSensitiveFiles: false };
+
+ const imageObject: IApDocument = {
+ type: 'Document',
+ mediaType: 'image/png',
+ url: 'http://host1.test/foo.png',
+ name: '',
+ };
+ const driveFile = await imageService.createImage(
+ await createRandomRemoteUser(resolver, personService),
+ imageObject,
+ );
+ assert.ok(!driveFile.isLink);
+
+ const sensitiveImageObject: IApDocument = {
+ type: 'Document',
+ mediaType: 'image/png',
+ url: 'http://host1.test/bar.png',
+ name: '',
+ sensitive: true,
+ };
+ const sensitiveDriveFile = await imageService.createImage(
+ await createRandomRemoteUser(resolver, personService),
+ sensitiveImageObject,
+ );
+ assert.ok(sensitiveDriveFile.isLink);
+ });
+ });
});
diff --git a/packages/backend/test/unit/chart.ts b/packages/backend/test/unit/chart.ts
index 5ac4cc18a2..40554d3a47 100644
--- a/packages/backend/test/unit/chart.ts
+++ b/packages/backend/test/unit/chart.ts
@@ -475,16 +475,16 @@ describe('Chart', () => {
await testIntersectionChart.addA('bob');
await testIntersectionChart.addB('carol');
await testIntersectionChart.save();
-
+
const chartHours = await testIntersectionChart.getChart('hour', 3, null);
const chartDays = await testIntersectionChart.getChart('day', 3, null);
-
+
assert.deepStrictEqual(chartHours, {
a: [2, 0, 0],
b: [1, 0, 0],
aAndB: [0, 0, 0],
});
-
+
assert.deepStrictEqual(chartDays, {
a: [2, 0, 0],
b: [1, 0, 0],
@@ -498,16 +498,16 @@ describe('Chart', () => {
await testIntersectionChart.addB('carol');
await testIntersectionChart.addB('alice');
await testIntersectionChart.save();
-
+
const chartHours = await testIntersectionChart.getChart('hour', 3, null);
const chartDays = await testIntersectionChart.getChart('day', 3, null);
-
+
assert.deepStrictEqual(chartHours, {
a: [2, 0, 0],
b: [2, 0, 0],
aAndB: [1, 0, 0],
});
-
+
assert.deepStrictEqual(chartDays, {
a: [2, 0, 0],
b: [2, 0, 0],