Ghost/ghost/recommendations/test/BookshelfRecommendationRepository.test.ts
Simon Backx 9abd466397
Renamed reason to description in recommendations table (#18527)
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
2023-10-09 11:19:44 -03:00

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'
}
]
}
);
});
});
});