Skip to content

Commit

Permalink
Add HTML meta tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mei23 authored and fs5m8 committed Nov 28, 2023
1 parent 7cedb5e commit 5bb35ec
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/misc/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,20 @@ export async function getJson(url: string, accept = 'application/json, */*', tim
return await res.json();
}

export async function getHtml(url: string, accept = 'text/html, */*', timeout = 10000, headers?: Record<string, string>): Promise<string> {
const res = await getResponse({
url,
method: 'GET',
headers: objectAssignWithLcKey({
'User-Agent': config.userAgent,
Accept: accept
}, headers || {}),
timeout
});

return await res.text();
}

export async function getResponse(args: { url: string, method: string, body?: string, headers: Record<string, string>, timeout?: number, size?: number }) {
logger.debug(`${args.method.toUpperCase()} ${args.url}\nHeaders: ${JSON.stringify(args.headers, null, 2)}${args.body ? `\n${args.body}` : ''}`);

Expand Down
189 changes: 188 additions & 1 deletion test/fetch-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ const CSP = `base-uri 'none'; default-src 'none'; script-src 'self' https://www.
describe('Fetch resource', () => {
let p: childProcess.ChildProcess;

let admin: any;
let instance: any;

let alice: any;
let avatar: any;
let alicesPost: any;
let image: any;
let alicesPostImage: any;
Expand All @@ -43,9 +47,43 @@ describe('Fetch resource', () => {

before(async () => {
p = await startServer();

// admin
admin = await signup({ username: 'admin' });

// update instance
await api('admin/update-meta', {
name: 'Instance Name',
description: 'Instance Desc',
}, admin);

instance = (await api('meta', {})).body;
console.log('instance', instance);

// signup
alice = await signup({ username: 'alice' });
//console.log('alice', alice);

// upload avatar
avatar = await uploadFile(alice);
//console.log('avatar', avatar);

// update profile
const token = alice.token;

const res = await api('i/update', {
name: 'Alice',
description: 'Alice Desc',
avatarId: avatar.id,
}, alice);

alice = res.body;
alice.token = token; // tokenはsignup以外では返ってこない
//console.log('alice-2', alice);

// post
alicesPost = await post(alice, {
text: 'test'
text: 'test',
});
//console.log('alicesPost', alicesPost);

Expand Down Expand Up @@ -290,4 +328,153 @@ describe('Fetch resource', () => {
assert.strictEqual(res.type, 'application/json; charset=utf-8');
}));
});

describe('HTML meta', () => {
const parse = (doc: Document) => {
return {
// Title
'title': doc.querySelector('title')?.textContent,
'og:title': doc.querySelector('meta[property="og:title"]')?.getAttribute('content'),
//'og:site_name': doc.querySelector('meta[property="og:site_name"]')?.getAttribute('content'),

// Description
'description': doc.querySelector('meta[name=description]')?.getAttribute('content'),
'og:description': doc.querySelector('meta[property="og:description"]')?.getAttribute('content'),

// Twitter card
'twitter:card': doc.querySelector('meta[name="twitter:card"]')?.getAttribute('content'),

// Misskey
'misskey:user-username': doc.querySelector('meta[name="misskey:user-username"]')?.getAttribute('content'),
'misskey:user-id': doc.querySelector('meta[name="misskey:user-id"]')?.getAttribute('content'),

// Generic - og
'og:url': doc.querySelector('meta[property="og:url"]')?.getAttribute('content'),
'og:image': doc.querySelector('meta[property="og:image"]')?.getAttribute('content'),
//og:published_time': doc.querySelector('meta[property="og:published_time"]')?.getAttribute('content'),

// Player - Twitter
'twitter:player': doc.querySelector('meta[name="twitter:player"]')?.getAttribute('content'),
'twitter:player:width': doc.querySelector('meta[name="twitter:player:width"]')?.getAttribute('content'),
'twitter:player:height': doc.querySelector('meta[name="twitter:player:height"]')?.getAttribute('content'),
'twitter:player:stream': doc.querySelector('meta[name="twitter:player:stream"]')?.getAttribute('content'),
'twitter:player:stream:content_type': doc.querySelector('meta[name="twitter:player:stream:content_type"]')?.getAttribute('content'),
};
}

it('/', async(async () => {
const parsed = parse(await getDocument('/'));

assert.deepStrictEqual(parsed, {
'title': instance.name,
'og:title': undefined,
//'og:site_name': instance.name,
'description': instance.description,
'og:description': undefined,
'twitter:card': undefined,
'misskey:user-username': undefined,
'misskey:user-id': undefined,
'og:url': undefined,
'og:image': null,
//'og:published_time': undefined,
'twitter:player': undefined,
'twitter:player:width': undefined,
'twitter:player:height': undefined,
'twitter:player:stream': undefined,
'twitter:player:stream:content_type': undefined,
});
}));

it('user', async(async () => {
const parsed = parse(await getDocument(`/@${alice.username}`));

assert.deepStrictEqual(parsed, {
'title': `${alice.name} (@${alice.username}) | ${instance.name}`,
'og:title': `${alice.name} (@${alice.username})`,
//'og:site_name': undefined,
'description': alice.description,
'og:description': alice.description,
'twitter:card': 'summary',
'misskey:user-username': alice.username,
'misskey:user-id': alice.id,
'og:url': `http://misskey.local/@${alice.username}`,
'og:image': null,
//'og:published_time': undefined,
'twitter:player': undefined,
'twitter:player:width': undefined,
'twitter:player:height': undefined,
'twitter:player:stream': undefined,
'twitter:player:stream:content_type': undefined,
});
}));

it('note', async(async () => {
const parsed = parse(await getDocument(`/notes/${alicesPost.id}`));

assert.deepStrictEqual(parsed, {
'title': `${alice.name} (@${alice.username}) | ${instance.name}`,
'og:title': `${alice.name} (@${alice.username})`,
//'og:site_name': undefined,
'description': alicesPost.text,
'og:description': alicesPost.text,
'twitter:card': 'summary',
'misskey:user-username': alice.username,
'misskey:user-id': alice.id,
'og:url': `http://misskey.local/notes/${alicesPost.id}`,
'og:image': alice.avatarUrl,
//'og:published_time': alicesPost.createtAt,
'twitter:player': undefined,
'twitter:player:width': undefined,
'twitter:player:height': undefined,
'twitter:player:stream': undefined,
'twitter:player:stream:content_type': undefined,
});
}));

it('note with image', async(async () => {
const parsed = parse(await getDocument(`/notes/${alicesPostImage.id}`));

assert.deepStrictEqual(parsed, {
'title': `${alice.name} (@${alice.username}) | ${instance.name}`,
'og:title': `${alice.name} (@${alice.username})`,
//'og:site_name': undefined,
'description': `${alicesPostImage.text} (1つのファイル)`,
'og:description': `${alicesPostImage.text} (1つのファイル)`,
'twitter:card': 'summary',
'misskey:user-username': alice.username,
'misskey:user-id': alice.id,
'og:url': `http://misskey.local/notes/${alicesPostImage.id}`,
'og:image': alicesPostImage.files[0].thumbnailUrl,
//'og:published_time': alicesPostImage.createtAt,
'twitter:player': undefined,
'twitter:player:width': undefined,
'twitter:player:height': undefined,
'twitter:player:stream': undefined,
'twitter:player:stream:content_type': undefined,
});
}));

it('note with video', async(async () => {
const parsed = parse(await getDocument(`/notes/${alicesPostVideo.id}`));

assert.deepStrictEqual(parsed, {
'title': `${alice.name} (@${alice.username}) | ${instance.name}`,
'og:title': `${alice.name} (@${alice.username})`,
//'og:site_name': undefined,
'description': `${alicesPostVideo.text} (1つのファイル)`,
'og:description': `${alicesPostVideo.text} (1つのファイル)`,
'twitter:card': 'summary',
'misskey:user-username': alice.username,
'misskey:user-id': alice.id,
'og:url': `http://misskey.local/notes/${alicesPostVideo.id}`,
'og:image': alicesPostVideo.files[0].thumbnailUrl,
//'og:published_time': alicesPostVideo.createtAt,
'twitter:player': undefined,
'twitter:player:width': undefined,
'twitter:player:height': undefined,
'twitter:player:stream': undefined,
'twitter:player:stream:content_type': undefined,
});
}));
});
});
Binary file added test/resources/anime.mp4
Binary file not shown.
1 change: 1 addition & 0 deletions test/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ redis:
host: localhost
port: 56311
id: aid
autoAdmin: true
7 changes: 7 additions & 0 deletions test/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,10 @@ export const simpleGet = async (path: string, accept = '*/*'): Promise<{ status?
req.end();
});
};

export const getDocument = async (path: string): Promise<Document> => {
const html = await getHtml(`http://localhost:${port}${path}`);
const { window } = new JSDOM(html);
const doc = window.document;
return doc;
};

0 comments on commit 5bb35ec

Please sign in to comment.