1- import * as request from 'supertest' ;
1+ import request from 'supertest' ;
22import app from '../index' ;
3- import { pool , closePool } from '../config/database' ; // Import pool for direct checks if needed
4-
5- // Close the database pool after all integration tests have run
6- afterAll ( async ( ) => {
7- await closePool ( ) ;
8- } ) ;
3+ import { closePool } from '../config/database' ;
94
105describe ( 'Question Service API (Integration)' , ( ) => {
11-
12- // Test the health check endpoint
13- it ( 'health check should return status and timestamp' , async ( ) => {
14- const res = await request ( app ) . get ( '/health' ) ;
15- expect ( [ 200 , 503 ] ) . toContain ( res . statusCode ) ;
16- expect ( res . body ) . toHaveProperty ( 'status' ) ;
17- expect ( res . body ) . toHaveProperty ( 'database' ) ;
18- expect ( res . body ) . toHaveProperty ( 'timestamp' ) ;
6+ afterAll ( async ( ) => {
7+ await closePool ( ) ;
198 } ) ;
209
21- // Test the GET /api/topics endpoint
22- it ( 'GET /api/topics should return an array or an error status' , async ( ) => {
23- const res = await request ( app ) . get ( '/api/topics' ) ;
24- expect ( [ 200 , 500 ] ) . toContain ( res . statusCode ) ; // Expect 200 or 500 (if DB not ready)
25- if ( res . statusCode === 200 ) {
26- expect ( Array . isArray ( res . body ) ) . toBe ( true ) ;
27- }
10+ describe ( 'Health Check' , ( ) => {
11+ it ( 'should return status and timestamp' , async ( ) => {
12+ const res = await request ( app ) . get ( '/health' ) ;
13+ expect ( [ 200 , 503 ] ) . toContain ( res . statusCode ) ;
14+ expect ( res . body ) . toHaveProperty ( 'status' ) ;
15+ expect ( res . body ) . toHaveProperty ( 'database' ) ;
16+ expect ( res . body ) . toHaveProperty ( 'timestamp' ) ;
17+ } ) ;
2818 } ) ;
2919
30- // Test the main POST /api/questions/select endpoint
31- it ( 'POST /api/questions/select should accept criteria and excludedIds' , async ( ) => {
32- const payload = {
33- criteria : { topic : 'Array' , difficulty : 'Easy' } , // Make sure 'Array' exists in your test DB
34- excludedIds : [ '00000000-0000-0000-0000-000000000000' ] // A fake UUID
35- } ;
20+ describe ( 'Questions API' , ( ) => {
21+ describe ( 'GET /api/questions' , ( ) => {
22+ it ( 'should return all questions' , async ( ) => {
23+ const res = await request ( app ) . get ( '/api/questions' ) ;
24+ expect ( res . statusCode ) . toBe ( 200 ) ;
25+ expect ( Array . isArray ( res . body ) ) . toBe ( true ) ;
26+ } ) ;
27+ } ) ;
3628
37- const res = await request ( app )
38- . post ( '/api/questions/select' )
39- . send ( payload )
40- . set ( 'Accept' , 'application/json' ) ;
29+ describe ( 'GET /api/questions/:id' , ( ) => {
30+ it ( 'should return question by id if exists' , async ( ) => {
31+ // First get all questions to get a valid ID
32+ const allQuestionsRes = await request ( app ) . get ( '/api/questions' ) ;
33+ if ( allQuestionsRes . body . length > 0 ) {
34+ const questionId = allQuestionsRes . body [ 0 ] . question_id ;
35+ const res = await request ( app ) . get ( `/api/questions/${ questionId } ` ) ;
36+ expect ( res . statusCode ) . toBe ( 200 ) ;
37+ expect ( res . body ) . toHaveProperty ( 'question_id' , questionId ) ;
38+ }
39+ } ) ;
4140
42- // Depending on seeded data, this may return 200 with a question or 404 if none found.
43- // 400 is also possible if criteria are bad. 500 if the DB connection fails.
44- expect ( [ 200 , 400 , 404 , 500 ] ) . toContain ( res . statusCode ) ;
41+ it ( 'should return 404 for non-existent question' , async ( ) => {
42+ const res = await request ( app ) . get ( '/api/questions/652c60dc-f518-4a7c-9c3c-bab6bf4b6cc0' ) ;
43+ expect ( res . statusCode ) . toBe ( 404 ) ;
44+ } ) ;
45+ } ) ;
4546
46- if ( res . statusCode === 200 ) {
47- expect ( res . body ) . toHaveProperty ( 'question_id' ) ;
48- expect ( res . body ) . toHaveProperty ( 'title ') ;
49- expect ( res . body ) . toHaveProperty ( 'difficulty' ) ;
50- // We know it's not the one we excluded
51- expect ( res . body . question_id ) . not . toBe ( '00000000-0000-0000-0000-000000000000' ) ;
52- }
47+ describe ( 'GET /api/topics' , ( ) => {
48+ it ( 'should return array of topics' , async ( ) => {
49+ const res = await request ( app ) . get ( '/api/topics ') ;
50+ expect ( res . statusCode ) . toBe ( 200 ) ;
51+ expect ( Array . isArray ( res . body ) ) . toBe ( true ) ;
52+ } ) ;
53+ } ) ;
5354
54- if ( res . statusCode === 404 ) {
55- expect ( res . body ) . toHaveProperty ( 'message' , 'No suitable question found for the given criteria.' ) ;
56- }
57- } ) ;
55+ describe ( 'POST /api/questions/select' , ( ) => {
56+ it ( 'should return a question matching criteria' , async ( ) => {
57+ const payload = {
58+ criteria : { topic : 'Array' , difficulty : 'Easy' } ,
59+ excludedIds : [ ]
60+ } ;
5861
59- it ( 'POST /api/questions/select validates body' , async ( ) => {
60- const res = await request ( app )
61- . post ( '/api/questions/select' )
62- . send ( { topic : 'Array' } ) ; // Missing criteria.difficulty and excludedIds
63-
64- // This expects your controller's validation logic to catch the bad body
65- expect ( res . statusCode ) . toBe ( 400 ) ;
66- expect ( res . body ) . toHaveProperty ( 'message' ) ;
67- } ) ;
62+ const res = await request ( app )
63+ . post ( '/api/questions/select' )
64+ . send ( payload ) ;
65+
66+ if ( res . statusCode === 200 ) {
67+ expect ( res . body ) . toMatchObject ( {
68+ question_id : expect . any ( String ) ,
69+ title : expect . any ( String ) ,
70+ difficulty : expect . stringMatching ( / ^ ( E a s y | M e d i u m | H a r d ) $ / )
71+ } ) ;
72+ } else {
73+ expect ( [ 404 ] ) . toContain ( res . statusCode ) ; // No matching questions found
74+ }
75+ } ) ;
76+
77+ it ( 'should validate request payload' , async ( ) => {
78+ const invalidPayload = {
79+ criteria : { topic : '' , difficulty : 'Invalid' }
80+ } ;
6881
69- } ) ;
82+ const res = await request ( app )
83+ . post ( '/api/questions/select' )
84+ . send ( invalidPayload ) ;
85+
86+ expect ( res . statusCode ) . toBe ( 400 ) ;
87+ expect ( res . body ) . toHaveProperty ( 'message' ) ;
88+ } ) ;
89+
90+ it ( 'should handle excludedIds correctly' , async ( ) => {
91+ // First get all questions
92+ const allQuestionsRes = await request ( app ) . get ( '/api/questions' ) ;
93+ if ( allQuestionsRes . body . length > 0 ) {
94+ const firstQuestion = allQuestionsRes . body [ 0 ] ;
95+
96+ const payload = {
97+ criteria : {
98+ topic : firstQuestion . topic ,
99+ difficulty : firstQuestion . difficulty
100+ } ,
101+ excludedIds : [ firstQuestion . question_id ]
102+ } ;
103+
104+ const res = await request ( app )
105+ . post ( '/api/questions/select' )
106+ . send ( payload ) ;
107+
108+ if ( res . statusCode === 200 ) {
109+ expect ( res . body . question_id ) . not . toBe ( firstQuestion . question_id ) ;
110+ } else {
111+ expect ( [ 404 ] ) . toContain ( res . statusCode ) ;
112+ }
113+ }
114+ } ) ;
115+ } ) ;
116+ } ) ;
117+ } ) ;
0 commit comments