init
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { detectImage, validateImage } from '../src/image.js';
|
||||
import { normalizeToWebp } from '../src/normalize.js';
|
||||
import { encodePng } from '../src/png.js';
|
||||
|
||||
test('detects generated png dimensions', () => {
|
||||
const png = encodePng(32, 24, () => [0, 255, 65, 255]);
|
||||
assert.deepEqual(detectImage(png), {
|
||||
format: 'png',
|
||||
ext: 'png',
|
||||
mime: 'image/png',
|
||||
width: 32,
|
||||
height: 24
|
||||
});
|
||||
});
|
||||
|
||||
test('rejects unsupported payloads', () => {
|
||||
assert.throws(
|
||||
() => validateImage(Buffer.from('<svg></svg>'), {
|
||||
maxBytes: 5 * 1024 * 1024,
|
||||
maxWidth: 6000,
|
||||
maxHeight: 6000,
|
||||
maxPixels: 20_000_000
|
||||
}),
|
||||
/Only PNG/
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects gif uploads', () => {
|
||||
const gif = Buffer.from('47494638396101000100800000000000ffffff2c00000000010001000002024401003b', 'hex');
|
||||
assert.throws(
|
||||
() => validateImage(gif, {
|
||||
maxBytes: 5 * 1024 * 1024,
|
||||
maxWidth: 6000,
|
||||
maxHeight: 6000,
|
||||
maxPixels: 20_000_000
|
||||
}),
|
||||
/Only PNG and JPEG/
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects non-square images when square uploads are required', () => {
|
||||
const png = encodePng(32, 24, () => [0, 255, 65, 255]);
|
||||
assert.throws(
|
||||
() => validateImage(png, {
|
||||
maxBytes: 5 * 1024 * 1024,
|
||||
maxWidth: 6000,
|
||||
maxHeight: 6000,
|
||||
maxPixels: 20_000_000,
|
||||
requireSquare: true
|
||||
}),
|
||||
/square/
|
||||
);
|
||||
});
|
||||
|
||||
test('normalizes png uploads to square webp', async () => {
|
||||
const png = encodePng(32, 32, () => [0, 255, 65, 255]);
|
||||
const normalized = await normalizeToWebp(png);
|
||||
|
||||
assert.equal(normalized.image.mime, 'image/webp');
|
||||
assert.equal(normalized.image.ext, 'webp');
|
||||
assert.equal(normalized.image.width, 32);
|
||||
assert.equal(normalized.image.height, 32);
|
||||
assert.equal(normalized.buffer.subarray(0, 4).toString('ascii'), 'RIFF');
|
||||
assert.equal(normalized.buffer.subarray(8, 12).toString('ascii'), 'WEBP');
|
||||
});
|
||||
@@ -0,0 +1,58 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import { createStore } from '../src/store.js';
|
||||
import { validateImage } from '../src/image.js';
|
||||
import { encodePng } from '../src/png.js';
|
||||
|
||||
test('stores memes in dated hash shards and paginates', async () => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'meme-protocol-'));
|
||||
const store = await createStore({ dataDir: dir });
|
||||
const buffer = encodePng(16, 16, () => [0, 255, 65, 255]);
|
||||
const image = validateImage(buffer, {
|
||||
maxBytes: 5 * 1024 * 1024,
|
||||
maxWidth: 6000,
|
||||
maxHeight: 6000,
|
||||
maxPixels: 20_000_000
|
||||
});
|
||||
const meme = await store.save({
|
||||
buffer,
|
||||
image,
|
||||
originalName: 'test.png',
|
||||
createdAt: '2026-05-08T12:00:00.000Z'
|
||||
});
|
||||
|
||||
assert.equal(store.count(), 1);
|
||||
assert.equal(store.list({ page: 1, pageSize: 12 }).memes[0].id, meme.id);
|
||||
assert.equal(store.list({ page: 1, pageSize: 12 }).memes[0].viewCount, 0);
|
||||
assert.match(store.get(meme.id).storageKey, /^memes\/2026\/05\/08\/[a-f0-9]{2}\/[a-f0-9]{2}\//);
|
||||
await fs.access(path.join(dir, store.get(meme.id).storageKey));
|
||||
});
|
||||
|
||||
test('increments view and download counters', async () => {
|
||||
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'meme-protocol-'));
|
||||
const store = await createStore({ dataDir: dir });
|
||||
const buffer = encodePng(16, 16, () => [0, 255, 65, 255]);
|
||||
const image = validateImage(buffer, {
|
||||
maxBytes: 5 * 1024 * 1024,
|
||||
maxWidth: 6000,
|
||||
maxHeight: 6000,
|
||||
maxPixels: 20_000_000,
|
||||
requireSquare: true
|
||||
});
|
||||
const meme = await store.save({
|
||||
buffer,
|
||||
image,
|
||||
originalName: 'test.png',
|
||||
createdAt: '2026-05-08T12:00:00.000Z'
|
||||
});
|
||||
|
||||
await store.incrementMetric(meme.id, 'viewCount');
|
||||
await store.incrementMetric(meme.id, 'downloadCount');
|
||||
|
||||
const listed = store.list({ page: 1, pageSize: 12 }).memes[0];
|
||||
assert.equal(listed.viewCount, 1);
|
||||
assert.equal(listed.downloadCount, 1);
|
||||
});
|
||||
Reference in New Issue
Block a user