1+ import { HttpStatus , INestApplication , ValidationPipe } from '@nestjs/common' ;
2+ import { Test } from '@nestjs/testing' ;
3+ import request from 'supertest' ;
4+
5+ import { AppModule } from '../../src/app.module' ;
6+ import { ArticleOutput } from '../../src/article/dtos/article-output.dto' ;
7+ import { AuthTokenOutput } from '../../src/auth/dtos/auth-token-output.dto' ;
8+ import { UserOutput } from '../../src/user/dtos/user-output.dto' ;
9+ import {
10+ closeDBAfterTest ,
11+ createDBEntities ,
12+ resetDBBeforeTest ,
13+ seedAdminUser ,
14+ } from '../test-utils' ;
15+
16+ describe ( 'ArticleController (e2e)' , ( ) => {
17+ let app : INestApplication ;
18+ let adminUser : UserOutput ;
19+ let authTokenForAdmin : AuthTokenOutput ;
20+
21+ beforeAll ( async ( ) => {
22+ await resetDBBeforeTest ( ) ;
23+ await createDBEntities ( ) ;
24+
25+ const moduleRef = await Test . createTestingModule ( {
26+ imports : [ AppModule ] ,
27+ } ) . compile ( ) ;
28+
29+ app = moduleRef . createNestApplication ( ) ;
30+ app . useGlobalPipes ( new ValidationPipe ( ) ) ;
31+ await app . init ( ) ;
32+
33+ ( { adminUser, authTokenForAdmin } = await seedAdminUser ( app ) ) ;
34+ } ) ;
35+
36+ const createArticleInput = {
37+ title : 'Test Article Title' ,
38+ post : 'This is a test article content for e2e testing.' ,
39+ } ;
40+
41+ const updateArticleInput = {
42+ title : 'Updated Test Article Title' ,
43+ post : 'This is the updated test article content.' ,
44+ } ;
45+
46+ let createdArticle : ArticleOutput ;
47+
48+ describe ( 'Create article' , ( ) => {
49+ it ( 'successfully creates an article' , async ( ) => {
50+ const response = await request ( app . getHttpServer ( ) )
51+ . post ( '/articles' )
52+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
53+ . send ( createArticleInput )
54+ . expect ( HttpStatus . CREATED ) ;
55+
56+ createdArticle = response . body . data ;
57+ expect ( createdArticle . title ) . toEqual ( createArticleInput . title ) ;
58+ expect ( createdArticle . post ) . toEqual ( createArticleInput . post ) ;
59+ expect ( createdArticle . author . id ) . toEqual ( adminUser . id ) ;
60+ expect ( createdArticle . author . name ) . toEqual ( adminUser . name ) ;
61+ expect ( createdArticle . id ) . toBeDefined ( ) ;
62+ expect ( createdArticle . createdAt ) . toBeDefined ( ) ;
63+ expect ( createdArticle . updatedAt ) . toBeDefined ( ) ;
64+ } ) ;
65+
66+ it ( 'Unauthorized error when BearerToken is not provided' , async ( ) => {
67+ return request ( app . getHttpServer ( ) )
68+ . post ( '/articles' )
69+ . send ( createArticleInput )
70+ . expect ( HttpStatus . UNAUTHORIZED ) ;
71+ } ) ;
72+
73+ it ( 'validation error when title is missing' , async ( ) => {
74+ const invalidInput = { post : 'Content without title' } ;
75+ return request ( app . getHttpServer ( ) )
76+ . post ( '/articles' )
77+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
78+ . send ( invalidInput )
79+ . expect ( HttpStatus . BAD_REQUEST ) ;
80+ } ) ;
81+ } ) ;
82+
83+ describe ( 'Get article' , ( ) => {
84+ it ( 'successfully gets an article by id' , async ( ) => {
85+ return request ( app . getHttpServer ( ) )
86+ . get ( `/articles/${ createdArticle . id } ` )
87+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
88+ . expect ( HttpStatus . OK )
89+ . expect ( ( res ) => {
90+ expect ( res . body . data . id ) . toEqual ( createdArticle . id ) ;
91+ expect ( res . body . data . title ) . toEqual ( createdArticle . title ) ;
92+ expect ( res . body . data . post ) . toEqual ( createdArticle . post ) ;
93+ } ) ;
94+ } ) ;
95+
96+ it ( 'throws NOT_FOUND when article doesnt exist' , ( ) => {
97+ return request ( app . getHttpServer ( ) )
98+ . get ( '/articles/99999' )
99+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
100+ . expect ( HttpStatus . NOT_FOUND ) ;
101+ } ) ;
102+
103+ it ( 'Unauthorized error when BearerToken is not provided' , async ( ) => {
104+ return request ( app . getHttpServer ( ) )
105+ . get ( `/articles/${ createdArticle . id } ` )
106+ . expect ( HttpStatus . UNAUTHORIZED ) ;
107+ } ) ;
108+ } ) ;
109+
110+ describe ( 'Get all articles' , ( ) => {
111+ it ( 'successfully gets all articles' , async ( ) => {
112+ return request ( app . getHttpServer ( ) )
113+ . get ( '/articles' )
114+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
115+ . expect ( HttpStatus . OK )
116+ . expect ( ( res ) => {
117+ expect ( res . body . data ) . toBeInstanceOf ( Array ) ;
118+ expect ( res . body . data . length ) . toBeGreaterThan ( 0 ) ;
119+ expect ( res . body . meta . count ) . toBeGreaterThan ( 0 ) ;
120+ } ) ;
121+ } ) ;
122+ } ) ;
123+
124+ describe ( 'Update article' , ( ) => {
125+ it ( 'successfully updates an article' , async ( ) => {
126+ return request ( app . getHttpServer ( ) )
127+ . patch ( `/articles/${ createdArticle . id } ` )
128+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
129+ . send ( updateArticleInput )
130+ . expect ( HttpStatus . OK )
131+ . expect ( ( res ) => {
132+ expect ( res . body . data . id ) . toEqual ( createdArticle . id ) ;
133+ expect ( res . body . data . title ) . toEqual ( updateArticleInput . title ) ;
134+ expect ( res . body . data . post ) . toEqual ( updateArticleInput . post ) ;
135+ expect ( res . body . data . updatedAt ) . not . toEqual ( createdArticle . updatedAt ) ;
136+ } ) ;
137+ } ) ;
138+
139+ it ( 'throws NOT_FOUND when article doesnt exist' , ( ) => {
140+ return request ( app . getHttpServer ( ) )
141+ . patch ( '/articles/99999' )
142+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
143+ . send ( updateArticleInput )
144+ . expect ( HttpStatus . NOT_FOUND ) ;
145+ } ) ;
146+
147+ it ( 'Unauthorized error when BearerToken is not provided' , async ( ) => {
148+ return request ( app . getHttpServer ( ) )
149+ . patch ( `/articles/${ createdArticle . id } ` )
150+ . send ( updateArticleInput )
151+ . expect ( HttpStatus . UNAUTHORIZED ) ;
152+ } ) ;
153+ } ) ;
154+
155+ describe ( 'Delete article' , ( ) => {
156+ it ( 'successfully deletes an article' , async ( ) => {
157+ return request ( app . getHttpServer ( ) )
158+ . delete ( `/articles/${ createdArticle . id } ` )
159+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
160+ . expect ( HttpStatus . NO_CONTENT ) ;
161+ } ) ;
162+
163+ it ( 'throws NOT_FOUND when trying to delete non-existent article' , ( ) => {
164+ return request ( app . getHttpServer ( ) )
165+ . delete ( '/articles/99999' )
166+ . set ( 'Authorization' , 'Bearer ' + authTokenForAdmin . accessToken )
167+ . expect ( HttpStatus . NOT_FOUND ) ;
168+ } ) ;
169+
170+ it ( 'Unauthorized error when BearerToken is not provided' , async ( ) => {
171+ return request ( app . getHttpServer ( ) )
172+ . delete ( '/articles/12345' )
173+ . expect ( HttpStatus . UNAUTHORIZED ) ;
174+ } ) ;
175+ } ) ;
176+
177+ afterAll ( async ( ) => {
178+ await app . close ( ) ;
179+ await closeDBAfterTest ( ) ;
180+ } ) ;
181+ } ) ;
0 commit comments