Skip to content

Commit

Permalink
Merge pull request #31 from leoferreiralima/feat/update-content
Browse files Browse the repository at this point in the history
feat: add content update and delete
  • Loading branch information
leoferreiralima committed Sep 27, 2023
2 parents 11ebbcd + 60cabcc commit 44b36ec
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 27 deletions.
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,3 +277,65 @@ const content = await tabNews.contents.getBySlug({
slug: '<slug>',
});
```

**Atualizar Conteúdo**

```js
import { TabNews } from 'tabnews-sdk';

const tabNews = new TabNews();

const content = await tabNews.contents.update({
slug: '<slug>',
username: '<username>',
title: 'title',
body: 'body',
status: 'published',
source_url: 'https://some.url',
});
```

```js
import { TabNews } from 'tabnews-sdk';

const tabNews = new TabNews();

await tabNews.session.create();

// Não é preciso passar o username pois internamente a bliblioteca ira realizar o fecth do usuario atual

const content = await tabNews.contents.update({
slug: '<slug>',
title: 'title',
body: 'body',
status: 'published',
source_url: 'https://some.url',
});
```

**Deletar Conteúdo**

```js
import { TabNews } from 'tabnews-sdk';

const tabNews = new TabNews();

const content = await tabNews.contents.delete({
slug: '<slug>',
username: '<username>',
});
```

```js
import { TabNews } from 'tabnews-sdk';

const tabNews = new TabNews();

await tabNews.session.create();

// Não é preciso passar o username pois internamente a bliblioteca ira realizar o fecth do usuario atual

const content = await tabNews.contents.delete({
slug: '<slug>',
});
```
84 changes: 84 additions & 0 deletions src/content/__snapshots__/content.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,48 @@ exports[`Content > create > should create content 1`] = `

exports[`Content > create > should throw an error when create content with invalid parameters 1`] = `"\\"body\\" possui o valor inválido \\"null\\"."`;

exports[`Content > delete > should delete content 1`] = `
{
"body": "body",
"children_deep_count": 2,
"created_at": 2023-09-19T12:16:04.812Z,
"deleted_at": null,
"id": "id",
"owner_id": "owner_id",
"owner_username": "username",
"parent_id": null,
"published_at": 2023-09-19T12:16:04.837Z,
"slug": "slug",
"source_url": "https://source.url.com/source",
"status": "published",
"tabcoins": 1,
"title": "title",
"updated_at": 2023-09-19T12:16:04.812Z,
}
`;

exports[`Content > delete > should delete content for current user 1`] = `
{
"body": "body",
"children_deep_count": 2,
"created_at": 2023-09-19T12:16:04.812Z,
"deleted_at": null,
"id": "id",
"owner_id": "owner_id",
"owner_username": "username",
"parent_id": null,
"published_at": 2023-09-19T12:16:04.837Z,
"slug": "slug",
"source_url": "https://source.url.com/source",
"status": "published",
"tabcoins": 1,
"title": "title",
"updated_at": 2023-09-19T12:16:04.812Z,
}
`;

exports[`Content > delete > should throw a api erro when content not found 1`] = `"O conteúdo informado não foi encontrado no sistema."`;

exports[`Content > get > should get all contents and pagination 1`] = `
{
"first_page": 1,
Expand Down Expand Up @@ -200,3 +242,45 @@ exports[`Content > get > should return correct page when is last page 2`] = `
exports[`Content > get > should throw an error when content not found 1`] = `"O conteúdo informado não foi encontrado no sistema."`;

exports[`Content > get > should throw an error when parameter is invalid 1`] = `"\\"page\\" deve possuir um valor mínimo de 1."`;

exports[`Content > update > should throw a api erro when content not found 1`] = `"O conteúdo informado não foi encontrado no sistema."`;

exports[`Content > update > should update content 1`] = `
{
"body": "body",
"children_deep_count": 2,
"created_at": 2023-09-19T12:16:04.812Z,
"deleted_at": null,
"id": "id",
"owner_id": "owner_id",
"owner_username": "username",
"parent_id": null,
"published_at": 2023-09-19T12:16:04.837Z,
"slug": "slug",
"source_url": "https://source.url.com/source",
"status": "published",
"tabcoins": 1,
"title": "title",
"updated_at": 2023-09-19T12:16:04.812Z,
}
`;

exports[`Content > update > should update content for current user 1`] = `
{
"body": "body",
"children_deep_count": 2,
"created_at": 2023-09-19T12:16:04.812Z,
"deleted_at": null,
"id": "id",
"owner_id": "owner_id",
"owner_username": "username",
"parent_id": null,
"published_at": 2023-09-19T12:16:04.837Z,
"slug": "slug",
"source_url": "https://source.url.com/source",
"status": "published",
"tabcoins": 1,
"title": "title",
"updated_at": 2023-09-19T12:16:04.812Z,
}
`;
154 changes: 146 additions & 8 deletions src/content/content.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
resetMocks,
} from '@test/utils';

import { GetContentListParams } from './interfaces';
import { GetContentListParams, UpdateContent } from './interfaces';

let tabNews: TabNews;

Expand Down Expand Up @@ -54,6 +54,13 @@ const contentDetail = {
};

describe('Content', () => {
const mockContent = (slug: string, user: string = username) => {
mockOnceResponse(
`${TABNEWS_ENDPOINTS.content}/${user}/${slug}`,
contentDetail,
);
};

beforeEach(() => {
tabNews = createTabNews();
});
Expand All @@ -78,13 +85,6 @@ describe('Content', () => {
);
};

const mockContent = (slug: string, user: string = username) => {
mockOnceResponse(
`${TABNEWS_ENDPOINTS.content}/${user}/${slug}`,
contentDetail,
);
};

it('should get all contents and pagination', async () => {
mockContents(linkHeader);

Expand Down Expand Up @@ -332,4 +332,142 @@ describe('Content', () => {
).rejects.toThrowErrorMatchingSnapshot();
});
});

describe('update', () => {
it('should update content', async () => {
const slug = 'slug';

mockContent(slug);

const updateContent: UpdateContent = {
slug,
title: 'title',
body: 'body',
status: 'published',
source_url: 'https://google.com',
};

const content = await tabNews.content.update({
username,
...updateContent,
});

expect(content).toMatchSnapshot();

const request = mockedRequest();

expectRequest(request).method.toBePatch();
expectRequest(request).body.toBe(updateContent);
});

it('should update content for current user', async () => {
const slug = 'slug';

mockOnceCurrentUser();

mockContent(slug);

const updateContent: UpdateContent = {
slug,
title: 'title',
body: 'body',
status: 'published',
source_url: 'https://google.com',
};

const content = await tabNews.content.update(updateContent);

expect(content).toMatchSnapshot();

const request = mockedRequest();

expectRequest(request).method.toBePatch();
expectRequest(request).body.toBe(updateContent);
});

it('should throw a api erro when content not found', () => {
const slug = 'slug';

mockOnceApiError(`${TABNEWS_ENDPOINTS.content}/${username}/${slug}`, {
name: 'NotFoundError',
message: 'O conteúdo informado não foi encontrado no sistema.',
action: 'Verifique se o "slug" está digitado corretamente.',
status_code: 404,
error_id: '4504533d-6dda-43c1-854d-2d7ddd49ab31',
request_id: '1345cace-8cdf-4200-ad4d-5c0975d35fb8',
error_location_code: 'CONTROLLER:CONTENT:PATCH_HANDLER:SLUG_NOT_FOUND',
key: 'slug',
});

expect(() =>
tabNews.content.update({
slug,
username,
}),
).rejects.toThrowErrorMatchingSnapshot();
});
});

describe('delete', () => {
it('should delete content', async () => {
const slug = 'slug';

mockContent(slug);

const content = await tabNews.content.delete({
slug,
username,
});

expect(content).toMatchSnapshot();

const request = mockedRequest();

expectRequest(request).method.toBePatch();
expectRequest(request).body.toBe({
status: 'deleted',
});
});

it('should delete content for current user', async () => {
const slug = 'slug';

mockOnceCurrentUser();

mockContent(slug);

const content = await tabNews.content.delete({ slug });

expect(content).toMatchSnapshot();

const request = mockedRequest();

expectRequest(request).method.toBePatch();
expectRequest(request).body.toBe({
status: 'deleted',
});
});

it('should throw a api erro when content not found', () => {
const slug = 'slug';

mockOnceApiError(`${TABNEWS_ENDPOINTS.content}/${username}/${slug}`, {
name: 'NotFoundError',
message: 'O conteúdo informado não foi encontrado no sistema.',
action: 'Verifique se o "slug" está digitado corretamente.',
status_code: 404,
error_id: '4504533d-6dda-43c1-854d-2d7ddd49ab31',
request_id: '1345cace-8cdf-4200-ad4d-5c0975d35fb8',
error_location_code: 'CONTROLLER:CONTENT:PATCH_HANDLER:SLUG_NOT_FOUND',
key: 'slug',
});

expect(() =>
tabNews.content.delete({
slug,
username,
}),
).rejects.toThrowErrorMatchingSnapshot();
});
});
});
30 changes: 28 additions & 2 deletions src/content/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,49 @@ import {
ContentResponse,
ContentStrategy,
CreateContent,
CreateContentResponse,
GetContentListParams,
GetContentParams,
UpdateContent,
} from './interfaces';

export class Content {
constructor(private readonly tabNews: TabNews) {}

async create(contentBody: CreateContent) {
const { body: content } = await this.tabNews.post<CreateContentResponse>({
const { body: content } = await this.tabNews.post<ContentDetailResponse>({
path: TABNEWS_ENDPOINTS.content,
body: contentBody,
});

return content;
}

async update({ username, ...contentUpdate }: UpdateContent) {
const { body: content } = await this.tabNews.patch<ContentDetailResponse>({
path: await this.getUrlForSlugAndUsername({
slug: contentUpdate.slug,
username,
}),
body: contentUpdate,
});

return content;
}

async delete({ username, slug }: GetContentParams) {
const { body: content } = await this.tabNews.patch<ContentDetailResponse>({
path: await this.getUrlForSlugAndUsername({
slug,
username,
}),
body: {
status: 'deleted',
},
});

return content;
}

async getAll({ username, ...params }: GetContentListParams = {}) {
const urlParams = new URLSearchParams();

Expand Down
Loading

0 comments on commit 44b36ec

Please sign in to comment.