Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: adicionar retorno de resultados para comentários #1601

Merged
merged 3 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion models/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ async function findWithStrategy(options = {}) {
const results = {};
const options = {};

if (!values?.where?.owner_username) {
if (!values?.where?.owner_username && values?.where?.parent_id === null) {
options.strategy = 'relevant_global';
}
values.order = 'published_at DESC';
Expand Down
18 changes: 16 additions & 2 deletions pages/api/v1/contents/index.public.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import controller from 'models/controller.js';
import event from 'models/event.js';
import firewall from 'models/firewall.js';
import notification from 'models/notification.js';
import removeMarkdown from 'models/remove-markdown';
import user from 'models/user.js';
import validator from 'models/validator.js';

Expand All @@ -35,6 +36,8 @@ function getValidationHandler(request, response, next) {
page: 'optional',
per_page: 'optional',
strategy: 'optional',
with_root: 'optional',
with_children: 'optional',
});

request.query = cleanValues;
Expand All @@ -48,11 +51,12 @@ async function getHandler(request, response) {
const results = await content.findWithStrategy({
strategy: request.query.strategy,
where: {
parent_id: null,
parent_id: request.query.with_children ? undefined : null,
status: 'published',
$not_null: request.query.with_root === false ? ['parent_id'] : undefined,
},
attributes: {
exclude: ['body'],
exclude: request.query.with_children ? undefined : ['body'],
},
page: request.query.page,
mthmcalixto marked this conversation as resolved.
Show resolved Hide resolved
per_page: request.query.per_page,
Expand All @@ -62,6 +66,16 @@ async function getHandler(request, response) {

const secureOutputValues = authorization.filterOutput(userTryingToList, 'read:content:list', contentList);

if (request.query.with_children) {
for (const content of secureOutputValues) {
if (content.parent_id) {
content.body = removeMarkdown(content.body, { maxLength: 255 });
} else {
delete content.body;
}
}
}

controller.injectPaginationHeaders(results.pagination, '/api/v1/contents', response);

return response.status(200).json(secureOutputValues);
Expand Down
177 changes: 172 additions & 5 deletions tests/integration/api/v1/contents/get.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ beforeAll(async () => {
});

describe('GET /api/v1/contents', () => {
beforeEach(async () => {
await orchestrator.dropAllTables();
await orchestrator.runPendingMigrations();
});
describe('Anonymous user (dropAllTables beforeEach)', () => {
beforeEach(async () => {
await orchestrator.dropAllTables();
await orchestrator.runPendingMigrations();
});

describe('Anonymous user', () => {
test('With CORS and Security Headers enabled', async () => {
const response = await fetch(`${orchestrator.webserverUrl}/api/v1/contents`);

Expand Down Expand Up @@ -1247,4 +1247,171 @@ describe('GET /api/v1/contents', () => {
expect(uuidVersion(responseBody.request_id)).toEqual(4);
});
});

describe('Anonymous user (dropAllTables beforeAll)', () => {
describe('with_children and with_root using different strategies', () => {
const rootSortedByOld = [];
const childSortedByOld = [];
const rootSortedByNew = [];
const childSortedByNew = [];
const rootSortedByTabCoins = [];
const childSortedByTabCoins = [];

beforeAll(async () => {
await orchestrator.dropAllTables();
await orchestrator.runPendingMigrations();

const createUser = async () => orchestrator.createUser();
const createContent = async (user, options) => orchestrator.createContent({ owner_id: user.id, ...options });
const createComment = async (user, parent, body) =>
createContent(user, { body, status: 'published', parent_id: parent.id });

const [firstUser, secondUser, thirdUser] = await Promise.all(Array.from({ length: 3 }, () => createUser()));

await createContent(firstUser, { title: 'Conteúdo "Draft"', status: 'draft' });

const firstRootContent = await createContent(secondUser, {
title: 'Primeiro conteúdo criado',
mthmcalixto marked this conversation as resolved.
Show resolved Hide resolved
status: 'published',
});

rootSortedByOld.push({
id: firstRootContent.id,
owner_id: secondUser.id,
parent_id: null,
slug: 'primeiro-conteudo-criado',
title: 'Primeiro conteúdo criado',
status: 'published',
source_url: null,
created_at: firstRootContent.created_at.toISOString(),
updated_at: firstRootContent.updated_at.toISOString(),
published_at: firstRootContent.published_at.toISOString(),
deleted_at: null,
owner_username: secondUser.username,
tabcoins: 2,
children_deep_count: 1,
});

await orchestrator.createRate(firstRootContent, 1);

const secondRootContent = await createContent(thirdUser, {
title: 'Segundo conteúdo criado',
status: 'published',
});

rootSortedByOld.push({
id: secondRootContent.id,
owner_id: thirdUser.id,
parent_id: null,
slug: 'segundo-conteudo-criado',
title: 'Segundo conteúdo criado',
status: 'published',
source_url: null,
created_at: secondRootContent.created_at.toISOString(),
updated_at: secondRootContent.updated_at.toISOString(),
published_at: secondRootContent.published_at.toISOString(),
deleted_at: null,
owner_username: thirdUser.username,
tabcoins: 1,
children_deep_count: 1,
});

const firstComment = await createComment(firstUser, secondRootContent, 'Comentário #1');
const secondComment = await createComment(thirdUser, firstRootContent, 'Comentário #2');
await orchestrator.createRate(firstComment, 1);

function createCommentExpect(comment, owner, parent, tabcoins = 0) {
return {
id: comment.id,
owner_id: owner.id,
parent_id: parent.id,
slug: comment.slug,
title: null,
body: comment.body,
status: 'published',
source_url: null,
created_at: comment.created_at.toISOString(),
updated_at: comment.updated_at.toISOString(),
published_at: comment.published_at.toISOString(),
deleted_at: null,
owner_username: owner.username,
tabcoins,
children_deep_count: 0,
};
}

childSortedByOld.push(
createCommentExpect(firstComment, firstUser, secondRootContent, 1),
createCommentExpect(secondComment, thirdUser, firstRootContent)
);

rootSortedByNew.push(...rootSortedByOld.slice().reverse());
childSortedByNew.push(...childSortedByOld.slice().reverse());

rootSortedByTabCoins.push(...rootSortedByNew.slice().sort((a, b) => b.tabcoins - a.tabcoins));
childSortedByTabCoins.push(...childSortedByNew.slice().sort((a, b) => b.tabcoins - a.tabcoins));
});

test.each([
{
content: 'relevant root',
params: [],
getExpected: () => rootSortedByTabCoins,
},
{
content: 'relevant root',
params: ['with_children=false'],
getExpected: () => rootSortedByTabCoins,
},
{
content: 'relevant root and children',
params: ['with_children=true'],
getExpected: () => [
rootSortedByTabCoins[0],
childSortedByTabCoins[0],
rootSortedByTabCoins[1],
childSortedByTabCoins[1],
],
},
{
content: 'new root',
params: ['with_children=false', 'with_root=true', 'strategy=new'],
getExpected: () => rootSortedByNew,
},
{
content: 'new root',
params: ['with_children=false', 'with_root=true', 'strategy=new'],
getExpected: () => rootSortedByNew,
},
{
content: 'new children',
params: ['with_children=true', 'with_root=false', 'strategy=new'],
getExpected: () => childSortedByNew,
},
{
content: 'new root and children',
params: ['with_children=true', 'strategy=new'],
getExpected: () => [...childSortedByNew, ...rootSortedByNew],
},
{
content: 'new root and children',
params: ['with_children=true', 'with_root=true', 'strategy=new'],
getExpected: () => [...childSortedByNew, ...rootSortedByNew],
},
{
content: 'new root',
params: ['with_root=true', 'strategy=new'],
getExpected: () => rootSortedByNew,
},
])('get $content with params: $params', async ({ params, getExpected }) => {
const url = `${orchestrator.webserverUrl}/api/v1/contents?${params.join('&')}`;

const response = await fetch(url);
const responseBody = await response.json();

expect(response.status).toEqual(200);
expect(responseBody).toStrictEqual(getExpected());
});
});
});
});
Loading