82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||
|
|
import { listUnitPriceExpr } from '../../lib/pricing/collection-valuation.js';
|
||
|
|
|
||
|
|
vi.mock('../../lib/sql.js', () => ({ sql: { query: vi.fn() } }));
|
||
|
|
vi.mock('../../lib/permission-middleware.js', () => ({
|
||
|
|
getUserFromRequest: vi.fn(),
|
||
|
|
}));
|
||
|
|
|
||
|
|
import { sql } from '../../lib/sql.js';
|
||
|
|
import { getUserFromRequest } from '../../lib/permission-middleware.js';
|
||
|
|
import handler from '../../pages/api/cards/owned.js';
|
||
|
|
|
||
|
|
const UNIT_PRICE_SQL = listUnitPriceExpr({ cardAlias: 'c' });
|
||
|
|
|
||
|
|
function createRes() {
|
||
|
|
const res = {
|
||
|
|
statusCode: 200,
|
||
|
|
body: null,
|
||
|
|
status(code) {
|
||
|
|
res.statusCode = code;
|
||
|
|
return res;
|
||
|
|
},
|
||
|
|
json(data) {
|
||
|
|
res.body = data;
|
||
|
|
return res;
|
||
|
|
},
|
||
|
|
};
|
||
|
|
return res;
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('GET /api/cards/owned sort', () => {
|
||
|
|
beforeEach(() => {
|
||
|
|
vi.clearAllMocks();
|
||
|
|
getUserFromRequest.mockResolvedValue({ userId: 1, email: 'a@b.c', role: 'user' });
|
||
|
|
sql.query.mockImplementation(async (queryText) => {
|
||
|
|
if (queryText.includes('COUNT(*)')) {
|
||
|
|
return { rows: [{ total: '0' }] };
|
||
|
|
}
|
||
|
|
if (queryText.includes('DISTINCT')) {
|
||
|
|
return { rows: [] };
|
||
|
|
}
|
||
|
|
return { rows: [] };
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('orders by effective price when sort=price&order=desc', async () => {
|
||
|
|
const req = {
|
||
|
|
method: 'GET',
|
||
|
|
query: { sort: 'price', order: 'desc' },
|
||
|
|
};
|
||
|
|
const res = createRes();
|
||
|
|
|
||
|
|
await handler(req, res);
|
||
|
|
|
||
|
|
expect(res.statusCode).toBe(200);
|
||
|
|
const cardsQueryCall = sql.query.mock.calls.find(([queryText]) =>
|
||
|
|
queryText.includes('INNER JOIN user_cards')
|
||
|
|
);
|
||
|
|
expect(cardsQueryCall).toBeDefined();
|
||
|
|
const queryText = cardsQueryCall[0];
|
||
|
|
expect(queryText).toContain(UNIT_PRICE_SQL);
|
||
|
|
expect(queryText).toContain('ORDER BY');
|
||
|
|
expect(queryText).toContain('DESC');
|
||
|
|
expect(queryText).toContain('NULLS LAST');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('defaults to name sort when sort param is invalid', async () => {
|
||
|
|
const req = {
|
||
|
|
method: 'GET',
|
||
|
|
query: { sort: 'invalid', order: 'asc' },
|
||
|
|
};
|
||
|
|
const res = createRes();
|
||
|
|
|
||
|
|
await handler(req, res);
|
||
|
|
|
||
|
|
const cardsQueryCall = sql.query.mock.calls.find(([queryText]) =>
|
||
|
|
queryText.includes('INNER JOIN user_cards')
|
||
|
|
);
|
||
|
|
expect(cardsQueryCall[0]).toContain('ORDER BY c.name ASC');
|
||
|
|
});
|
||
|
|
});
|