convert all remaining backend code to TimeService

This commit is contained in:
Hazelnoot 2025-10-01 20:26:18 -04:00
parent 9c96dca5a6
commit 3a92471b68
11 changed files with 74 additions and 46 deletions

View file

@ -145,6 +145,8 @@ export interface PromiseTimerHandle<T = void> extends PromiseLike<T> {
@Injectable()
export class NativeTimeService extends TimeService<NativeTimer> implements OnApplicationShutdown {
public get now(): number {
// This is the one place that actually *should* have it
// eslint-disable-next-line no-restricted-properties
return Date.now();
}

View file

@ -14,16 +14,17 @@ import { CustomEmojiService } from '@/core/CustomEmojiService.js';
import { type UserWebhookPayload, UserWebhookService } from '@/core/UserWebhookService.js';
import { QueueService } from '@/core/QueueService.js';
import { IdService } from '@/core/IdService.js';
import { TimeService } from '@/core/TimeService.js';
import { ModeratorInactivityRemainingTime } from '@/queue/processors/CheckModeratorsActivityProcessorService.js';
const oneDayMillis = 24 * 60 * 60 * 1000;
function generateDummyUser(override?: Partial<MiUser>): MiUser {
function generateDummyUser(now: number, override?: Partial<MiUser>): MiUser {
return {
id: 'dummy-user-1',
updatedAt: new Date(Date.now() - oneDayMillis * 7),
lastFetchedAt: new Date(Date.now() - oneDayMillis * 5),
lastActiveDate: new Date(Date.now() - oneDayMillis * 3),
updatedAt: new Date(now - oneDayMillis * 7),
lastFetchedAt: new Date(now - oneDayMillis * 5),
lastActiveDate: new Date(now - oneDayMillis * 3),
hideOnlineStatus: false,
username: 'dummy1',
usernameLower: 'dummy1',
@ -132,31 +133,34 @@ function generateDummyNote(override?: Partial<MiNote>): MiNote {
};
}
const dummyUser1 = generateDummyUser();
const dummyUser2 = generateDummyUser({
id: 'dummy-user-2',
updatedAt: new Date(Date.now() - oneDayMillis * 30),
lastFetchedAt: new Date(Date.now() - oneDayMillis),
lastActiveDate: new Date(Date.now() - oneDayMillis),
username: 'dummy2',
usernameLower: 'dummy2',
name: 'DummyUser2',
followersCount: 40,
followingCount: 50,
notesCount: 900,
});
const dummyUser3 = generateDummyUser({
id: 'dummy-user-3',
updatedAt: new Date(Date.now() - oneDayMillis * 15),
lastFetchedAt: new Date(Date.now() - oneDayMillis * 2),
lastActiveDate: new Date(Date.now() - oneDayMillis * 2),
username: 'dummy3',
usernameLower: 'dummy3',
name: 'DummyUser3',
followersCount: 60,
followingCount: 70,
notesCount: 15900,
});
function makeDummyUsers(now: number) {
const dummyUser1 = generateDummyUser(now);
const dummyUser2 = generateDummyUser(now, {
id: 'dummy-user-2',
updatedAt: new Date(now - oneDayMillis * 30),
lastFetchedAt: new Date(now - oneDayMillis),
lastActiveDate: new Date(now - oneDayMillis),
username: 'dummy2',
usernameLower: 'dummy2',
name: 'DummyUser2',
followersCount: 40,
followingCount: 50,
notesCount: 900,
});
const dummyUser3 = generateDummyUser(now, {
id: 'dummy-user-3',
updatedAt: new Date(now - oneDayMillis * 15),
lastFetchedAt: new Date(now - oneDayMillis * 2),
lastActiveDate: new Date(now - oneDayMillis * 2),
username: 'dummy3',
usernameLower: 'dummy3',
name: 'DummyUser3',
followersCount: 60,
followingCount: 70,
notesCount: 15900,
});
return { dummyUser1, dummyUser2, dummyUser3 };
}
@Injectable()
export class WebhookTestService {
@ -169,6 +173,7 @@ export class WebhookTestService {
private systemWebhookService: SystemWebhookService,
private queueService: QueueService,
private readonly idService: IdService,
private readonly timeService: TimeService,
) {
}
@ -207,6 +212,8 @@ export class WebhookTestService {
this.queueService.userWebhookDeliver(merged, type, contents, { attempts: 1 });
};
const { dummyUser1, dummyUser2, dummyUser3 } = makeDummyUsers(this.timeService.now);
const dummyNote1 = generateDummyNote({
userId: dummyUser1.id,
user: dummyUser1,
@ -311,6 +318,8 @@ export class WebhookTestService {
this.queueService.systemWebhookDeliver(merged, type, contents, { attempts: 1 });
};
const { dummyUser1, dummyUser2, dummyUser3 } = makeDummyUsers(this.timeService.now);
switch (params.type) {
case 'abuseReport': {
send('abuseReport', await this.generateAbuseReport({
@ -396,13 +405,13 @@ export class WebhookTestService {
return {
id: note.id,
threadId: note.threadId ?? note.id,
createdAt: new Date().toISOString(),
createdAt: this.timeService.date.toISOString(),
deletedAt: null,
text: note.text,
cw: note.cw,
userId: note.userId,
userHost: note.userHost ?? null,
user: await this.toPackedUserLite(note.user ?? generateDummyUser()),
user: await this.toPackedUserLite(note.user ?? generateDummyUser(this.timeService.now)),
replyId: note.replyId,
renoteId: note.renoteId,
isHidden: false,
@ -486,7 +495,7 @@ export class WebhookTestService {
uri: null,
movedTo: null,
alsoKnownAs: [],
createdAt: new Date().toISOString(),
createdAt: this.timeService.date.toISOString(),
updatedAt: user.updatedAt?.toISOString() ?? null,
lastFetchedAt: user.lastFetchedAt?.toISOString() ?? null,
bannerUrl: user.bannerId == null ? null : user.bannerUrl,

View file

@ -14,6 +14,7 @@ import { UserKeypairService } from '@/core/UserKeypairService.js';
import { ApUtilityService } from '@/core/activitypub/ApUtilityService.js';
import { HttpRequestService } from '@/core/HttpRequestService.js';
import { LoggerService } from '@/core/LoggerService.js';
import { TimeService } from '@/core/TimeService.js';
import { bindThis } from '@/decorators.js';
import type Logger from '@/logger.js';
import { validateContentTypeSetAsActivityPub } from '@/core/activitypub/misc/validator.js';
@ -40,7 +41,7 @@ type PrivateKey = {
};
export class ApRequestCreator {
static createSignedPost(args: { key: PrivateKey, url: string, body: string, digest?: string, additionalHeaders: Record<string, string> }): Signed {
static createSignedPost(args: { key: PrivateKey, url: string, body: string, digest?: string, additionalHeaders: Record<string, string>, now: Date | string | number }): Signed {
const u = new URL(args.url);
const digestHeader = args.digest ?? this.createDigest(args.body);
@ -48,7 +49,7 @@ export class ApRequestCreator {
url: u.href,
method: 'POST',
headers: this.#objectAssignWithLcKey({
'Date': new Date().toUTCString(),
'Date': new Date(args.now).toUTCString(),
'Host': u.host,
'Content-Type': 'application/activity+json',
'Digest': digestHeader,
@ -69,7 +70,7 @@ export class ApRequestCreator {
return `SHA-256=${crypto.createHash('sha256').update(body).digest('base64')}`;
}
static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string> }): Signed {
static createSignedGet(args: { key: PrivateKey, url: string, additionalHeaders: Record<string, string>, now: Date | string | number }): Signed {
const u = new URL(args.url);
const request: Request = {
@ -77,7 +78,7 @@ export class ApRequestCreator {
method: 'GET',
headers: this.#objectAssignWithLcKey({
'Accept': 'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
'Date': new Date().toUTCString(),
'Date': new Date(args.now).toUTCString(),
'Host': new URL(args.url).host,
}, args.additionalHeaders),
};
@ -150,6 +151,7 @@ export class ApRequestService {
private httpRequestService: HttpRequestService,
private loggerService: LoggerService,
private readonly apUtilityService: ApUtilityService,
private readonly timeService: TimeService,
) {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
this.logger = this.loggerService?.getLogger('ap-request'); // なぜか TypeError: Cannot read properties of undefined (reading 'getLogger') と言われる
@ -171,6 +173,7 @@ export class ApRequestService {
digest,
additionalHeaders: {
},
now: this.timeService.now,
});
await this.httpRequestService.send(url, {
@ -200,6 +203,7 @@ export class ApRequestService {
url,
additionalHeaders: {
},
now: this.timeService.now,
});
const res = await this.httpRequestService.send(url, {