9abd466397
fixes https://github.com/TryGhost/Product/issues/4005 We no longer use the 'reason' of a recommendation, but allow a flexible description instead. Because this is a breaking change in the API, we do this before making this feature GA. - Added new database utils for renaming a column - Added new migration to rename the column - Updated all references in code
246 lines
7.8 KiB
TypeScript
246 lines
7.8 KiB
TypeScript
import assert from 'assert/strict';
|
|
import {BookshelfRecommendationRepository, Recommendation} from '../src';
|
|
import sinon from 'sinon';
|
|
|
|
describe('BookshelfRecommendationRepository', function () {
|
|
afterEach(function () {
|
|
sinon.restore();
|
|
});
|
|
|
|
it('toPrimitive', async function () {
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: undefined
|
|
});
|
|
assert.deepEqual(
|
|
repository.toPrimitive(Recommendation.create({
|
|
id: 'id',
|
|
title: 'title',
|
|
description: 'description',
|
|
excerpt: 'excerpt',
|
|
featuredImage: new URL('https://example.com'),
|
|
favicon: new URL('https://example.com'),
|
|
url: new URL('https://example.com'),
|
|
oneClickSubscribe: true,
|
|
createdAt: new Date('2021-01-01'),
|
|
updatedAt: new Date('2021-01-02')
|
|
})),
|
|
{
|
|
id: 'id',
|
|
title: 'title',
|
|
description: 'description',
|
|
excerpt: 'excerpt',
|
|
featured_image: 'https://example.com/',
|
|
favicon: 'https://example.com/',
|
|
url: 'https://example.com/',
|
|
one_click_subscribe: true,
|
|
created_at: new Date('2021-01-01'),
|
|
updated_at: new Date('2021-01-02')
|
|
}
|
|
);
|
|
});
|
|
|
|
it('modelToEntity', async function () {
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: undefined
|
|
});
|
|
const entity = repository.modelToEntity({
|
|
id: 'id',
|
|
get: (key: string) => {
|
|
return {
|
|
title: 'title',
|
|
description: 'description',
|
|
excerpt: 'excerpt',
|
|
featured_image: 'https://example.com/',
|
|
favicon: 'https://example.com/',
|
|
url: 'https://example.com/',
|
|
one_click_subscribe: true,
|
|
created_at: new Date('2021-01-01'),
|
|
updated_at: new Date('2021-01-02')
|
|
}[key];
|
|
}
|
|
} as any);
|
|
|
|
assert.deepEqual(
|
|
entity,
|
|
Recommendation.create({
|
|
id: 'id',
|
|
title: 'title',
|
|
description: 'description',
|
|
excerpt: 'excerpt',
|
|
featuredImage: new URL('https://example.com'),
|
|
favicon: new URL('https://example.com'),
|
|
url: new URL('https://example.com'),
|
|
oneClickSubscribe: true,
|
|
createdAt: new Date('2021-01-01'),
|
|
updatedAt: new Date('2021-01-02')
|
|
})
|
|
);
|
|
});
|
|
|
|
it('modelToEntity returns null on errors', async function () {
|
|
const captureException = sinon.stub();
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: {
|
|
captureException
|
|
}
|
|
});
|
|
|
|
sinon.stub(Recommendation, 'create').throws(new Error('test'));
|
|
const entity = repository.modelToEntity({
|
|
id: 'id',
|
|
get: () => {
|
|
return null;
|
|
}
|
|
} as any);
|
|
|
|
assert.deepEqual(
|
|
entity,
|
|
null
|
|
);
|
|
sinon.assert.calledOnce(captureException);
|
|
});
|
|
|
|
it('getByUrl returns null if not found', async function () {
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: undefined
|
|
});
|
|
const stub = sinon.stub(repository, 'getAll').returns(Promise.resolve([]));
|
|
const entity = await repository.getByUrl(new URL('https://example.com'));
|
|
|
|
assert.deepEqual(
|
|
entity,
|
|
null
|
|
);
|
|
sinon.assert.calledOnce(stub);
|
|
});
|
|
|
|
it('getByUrl returns if matching hostname', async function () {
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: undefined
|
|
});
|
|
const recommendation = Recommendation.create({
|
|
id: 'id',
|
|
title: 'title',
|
|
description: 'description',
|
|
excerpt: 'excerpt',
|
|
featuredImage: new URL('https://example.com'),
|
|
favicon: new URL('https://example.com'),
|
|
url: new URL('https://example.com/path'),
|
|
oneClickSubscribe: true,
|
|
createdAt: new Date('2021-01-01'),
|
|
updatedAt: new Date('2021-01-02')
|
|
});
|
|
const stub = sinon.stub(repository, 'getAll').returns(Promise.resolve([
|
|
recommendation
|
|
]));
|
|
const entity = await repository.getByUrl(new URL('https://www.example.com/path'));
|
|
|
|
assert.equal(
|
|
entity,
|
|
recommendation
|
|
);
|
|
sinon.assert.calledOnce(stub);
|
|
});
|
|
|
|
it('getByUrl returns null if not matching path', async function () {
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: undefined
|
|
});
|
|
const recommendation = Recommendation.create({
|
|
id: 'id',
|
|
title: 'title',
|
|
description: 'description',
|
|
excerpt: 'excerpt',
|
|
featuredImage: new URL('https://example.com'),
|
|
favicon: new URL('https://example.com'),
|
|
url: new URL('https://example.com/other-path'),
|
|
oneClickSubscribe: true,
|
|
createdAt: new Date('2021-01-01'),
|
|
updatedAt: new Date('2021-01-02')
|
|
});
|
|
const stub = sinon.stub(repository, 'getAll').returns(Promise.resolve([
|
|
recommendation
|
|
]));
|
|
const entity = await repository.getByUrl(new URL('https://www.example.com/path'));
|
|
|
|
assert.equal(
|
|
entity,
|
|
null
|
|
);
|
|
sinon.assert.calledOnce(stub);
|
|
});
|
|
|
|
it('getFieldToColumnMap returns', async function () {
|
|
const captureException = sinon.stub();
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: {
|
|
captureException
|
|
}
|
|
});
|
|
|
|
assert.ok(repository.getFieldToColumnMap());
|
|
});
|
|
|
|
it('applyCustomQuery returns', async function () {
|
|
const captureException = sinon.stub();
|
|
const repository = new BookshelfRecommendationRepository({} as any, {
|
|
sentry: {
|
|
captureException
|
|
}
|
|
});
|
|
|
|
const builder = {
|
|
select: function (arg: any) {
|
|
if (typeof arg === 'function') {
|
|
arg(this);
|
|
}
|
|
},
|
|
count: function () {
|
|
return this;
|
|
},
|
|
from: function () {
|
|
return this;
|
|
},
|
|
where: function () {
|
|
return this;
|
|
},
|
|
as: function () {
|
|
return this;
|
|
},
|
|
client: {
|
|
raw: function () {
|
|
return '';
|
|
}
|
|
}
|
|
} as any;
|
|
|
|
assert.doesNotThrow(() => {
|
|
repository.applyCustomQuery(
|
|
builder,
|
|
{
|
|
include: ['clickCount', 'subscriberCount']
|
|
}
|
|
);
|
|
});
|
|
|
|
assert.doesNotThrow(() => {
|
|
repository.applyCustomQuery(
|
|
builder,
|
|
{
|
|
include: [],
|
|
order: [
|
|
{
|
|
field: 'clickCount',
|
|
direction: 'asc'
|
|
},
|
|
{
|
|
field: 'subscriberCount',
|
|
direction: 'desc'
|
|
}
|
|
]
|
|
}
|
|
);
|
|
});
|
|
});
|
|
});
|