@cosmospro/cosmospro-msw
v1.0.1
Published
Biblioteca com a implementação odata para utilização dentro do MSW, permitindo mock de apis odata para teste.
Maintainers
Readme
@cosmospro/cosmospro-msw
Wrapper declarativo de MSW para mockar Custom Views e Custom Actions do Cosmos Pro em testes e desenvolvimento — sem precisar conhecer MSW ou OData diretamente.
A biblioteca encapsula o protocolo OData v4 (filtros, paginação, ordenação, agregação) e o endpoint ExecuteCustomAction em duas funções declarativas: você informa o nome e os dados/handler, e a lib cuida do resto.
Internamente apoia-se em @cosmospro/msw-odata para o parser OData e os helpers de autenticação.
Instalação
npm i -D @cosmospro/cosmospro-msw mswmsw é uma peer dependency — instale a versão 2.x.
Quickstart (Vitest + Node)
import { setupServer } from 'msw/node';
import { mockCustomView, mockCustomAction } from '@cosmospro/cosmospro-msw';
interface Produto { id: number; nome: string; preco: number }
const produtos: Produto[] = [
{ id: 1, nome: 'Notebook', preco: 5000 },
{ id: 2, nome: 'Mouse', preco: 80 },
];
const server = setupServer(
mockCustomView<Produto>('ProdutosMaisVendidos', produtos),
mockCustomAction('EnviarEmail', ({ body }) => ({ status: 'sent' })),
);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());No browser, troque por setupWorker de msw/browser.
mockCustomView<T>(name, data, options?)
Intercepta POST {baseUrl}/odata/CustomViews(Name='{name}')/ExecuteAndReceiveData e responde com a coleção data filtrada/paginada/ordenada conforme os parâmetros OData v4 da query string.
mockCustomView<Produto>('ProdutosMaisVendidos', produtos, {
baseUrl: 'http://api.example.com', // opcional - default: qualquer host
auth: 'meu-bearer-token', // string => Bearer | AuthPredicate => custom
delay: 200, // ms de latencia simulada
onParams: (params) => {
// Recebe { Parameters: {...} } do body - util para datasets dinamicos
return produtos.filter((p) => p.preco >= Number(params.MinPrice));
},
});OData suportado (delegado ao @cosmospro/msw-odata):
$filter, $orderby, $top, $skip, $select, $count, $expand, $apply.
Resposta:
{
"@odata.count": 42,
"value": [ /* itens */ ]
}mockCustomAction(name, handler, options?)
Intercepta POST {baseUrl}/api/ExecuteCustomAction/ExecuteAction?ActionName={name}&api-version=1.0. O handler recebe um contexto e devolve qualquer JSON-serializavel (ou um Response via ctx.reply.*).
mockCustomAction('AtualizarStatus', async ({ query, body, reply }) => {
if (!body || typeof body !== 'object') {
return reply.badRequest('body obrigatorio');
}
return { id: query.id, status: (body as any).novoStatus };
});Contexto disponivel:
| Campo | Tipo | Descricao |
| --- | --- | --- |
| request | Request | Requisicao original (Fetch API) |
| query | Record<string,string> | Query params (sem ActionName nem api-version) |
| body | unknown | JSON parseado do body, ou null se vazio/nao-JSON |
| reply | ReplyHelpers | Atalhos: json, ok, created, noContent, badRequest, unauthorized, forbidden, notFound |
O retorno do handler e envelopado automaticamente em HttpResponse.json(...). Se voce quer controlar status/headers, retorne um Response diretamente (use os helpers de ctx.reply).
Multiplas chamadas para mockCustomAction no mesmo setupServer convivem sem conflito: cada uma so responde quando o ActionName da query bate com o registrado.
Autenticacao
A opcao auth aceita:
- String - tratada como Bearer token (match exato em
Authorization: Bearer <token>). - Funcao
AuthPredicate-(request: Request) => boolean | Promise<boolean>.
Quando o predicado retorna false, a resposta e 401 Unauthorized.
import { authBearer } from '@cosmospro/cosmospro-msw';
mockCustomView('X', data, { auth: 'token' }); // bearer simples
mockCustomView('X', data, { auth: authBearer((t) => t.startsWith('sk_')) }); // validacao custom
mockCustomView('X', data, { auth: (req) => req.headers.has('x-key') }); // predicate customLimitacoes conhecidas
- Custom Views sao tratadas exclusivamente como OData v4 (formato real do Cosmos Pro).
- Custom Actions com upload multipart de arquivos ainda nao sao cobertas (apenas body JSON).
- A regex de match assume URL absoluta na request -
setupWorker/setupServerinterceptam normalmente; em ambientes que reescrevem hosts, configurebaseUrlexplicitamente.
