@@ -2,13 +2,27 @@ import { mkdtempSync } from "fs";
22import { tmpdir } from "os" ;
33import { join } from "path" ;
44import request from "supertest" ;
5- import { afterEach , describe , expect , it } from "vitest" ;
5+ import { afterEach , beforeEach , describe , expect , it , vi } from "vitest" ;
66import XLSX from "xlsx" ;
7+
8+ const mocks = vi . hoisted ( ( ) => ( {
9+ run : vi . fn ( ) ,
10+ } ) ) ;
11+
12+ vi . mock ( "../../src/app.js" , ( ) => ( {
13+ run : mocks . run ,
14+ } ) ) ;
15+
716import { createJobsApiApp } from "../../src/jobsApiApp.js" ;
817
918describe ( "jobs API" , ( ) => {
1019 let tmpDir ;
1120
21+ beforeEach ( ( ) => {
22+ vi . clearAllMocks ( ) ;
23+ mocks . run . mockResolvedValue ( undefined ) ;
24+ } ) ;
25+
1226 afterEach ( ( ) => {
1327 tmpDir = undefined ;
1428 } ) ;
@@ -63,4 +77,67 @@ describe("jobs API", () => {
6377 const res = await request ( app ) . get ( "/api/jobs" ) . query ( { file : "nao-existe.xlsx" } ) . expect ( 404 ) ;
6478 expect ( res . body . message ) . toBe ( "Arquivo solicitado nao encontrado." ) ;
6579 } ) ;
80+
81+ it ( "POST /api/scraper/run executa scraper e retorna metadados" , async ( ) => {
82+ tmpDir = mkdtempSync ( join ( tmpdir ( ) , "jobs-api-" ) ) ;
83+ const workbook = XLSX . utils . book_new ( ) ;
84+ const sheet = XLSX . utils . json_to_sheet ( [ { titulo : "x" } ] ) ;
85+ XLSX . utils . book_append_sheet ( workbook , sheet , "Vagas" ) ;
86+ XLSX . writeFile ( workbook , join ( tmpDir , "resultado.xlsx" ) ) ;
87+
88+ const app = createJobsApiApp ( { outputDir : tmpDir } ) ;
89+ const res = await request ( app ) . post ( "/api/scraper/run" ) . expect ( 200 ) ;
90+
91+ expect ( mocks . run ) . toHaveBeenCalledTimes ( 1 ) ;
92+ expect ( res . body . ok ) . toBe ( true ) ;
93+ expect ( res . body . file ) . toBe ( "resultado.xlsx" ) ;
94+ expect ( res . body . totalFiles ) . toBe ( 1 ) ;
95+ } ) ;
96+
97+ it ( "POST /api/scraper/run retorna 409 quando ja existe execucao ativa" , async ( ) => {
98+ tmpDir = mkdtempSync ( join ( tmpdir ( ) , "jobs-api-" ) ) ;
99+ let finishRun ;
100+ mocks . run . mockImplementation (
101+ ( ) =>
102+ new Promise ( ( resolve ) => {
103+ finishRun = resolve ;
104+ } ) ,
105+ ) ;
106+
107+ const app = createJobsApiApp ( { outputDir : tmpDir } ) ;
108+
109+ const firstRequest = new Promise ( ( resolve , reject ) => {
110+ request ( app )
111+ . post ( "/api/scraper/run" )
112+ . end ( ( error , response ) => {
113+ if ( error ) {
114+ reject ( error ) ;
115+ return ;
116+ }
117+ resolve ( response ) ;
118+ } ) ;
119+ } ) ;
120+
121+ await vi . waitFor ( ( ) => {
122+ expect ( mocks . run ) . toHaveBeenCalledTimes ( 1 ) ;
123+ } ) ;
124+
125+ const conflict = await request ( app ) . post ( "/api/scraper/run" ) . expect ( 409 ) ;
126+ expect ( conflict . body . message ) . toBe ( "O scraper ja esta em execucao." ) ;
127+
128+ finishRun ( ) ;
129+ const firstResult = await firstRequest ;
130+ expect ( firstResult . status ) . toBe ( 200 ) ;
131+ } ) ;
132+
133+ it ( "POST /api/scraper/run retorna 500 quando scraper falha" , async ( ) => {
134+ tmpDir = mkdtempSync ( join ( tmpdir ( ) , "jobs-api-" ) ) ;
135+ mocks . run . mockRejectedValue ( new Error ( "falha no scraper" ) ) ;
136+
137+ const app = createJobsApiApp ( { outputDir : tmpDir } ) ;
138+ const res = await request ( app ) . post ( "/api/scraper/run" ) . expect ( 500 ) ;
139+
140+ expect ( res . body . message ) . toBe ( "Erro ao executar o scraper." ) ;
141+ expect ( res . body . error ) . toBe ( "falha no scraper" ) ;
142+ } ) ;
66143} ) ;
0 commit comments