@@ -6,90 +6,165 @@ import {
66} from 'vitest'
77import createConcept from '../handler'
88import conceptIdExists from '../../utils/conceptIdExists'
9+ import getConceptId from '../../utils/getConceptId'
910import { getApplicationConfig } from '../../utils/getConfig'
1011import { sparqlRequest } from '../../utils/sparqlRequest'
1112
1213// Mock the dependencies
1314vi . mock ( '../../utils/conceptIdExists' )
15+ vi . mock ( '../../utils/getConceptId' )
1416vi . mock ( '../../utils/getConfig' )
1517vi . mock ( '../../utils/sparqlRequest' )
1618
1719describe ( 'createConcept' , ( ) => {
18- const mockEvent = {
19- body : '<rdf:RDF>...</rdf:RDF>' ,
20- pathParameters : { conceptId : '123' }
21- }
22-
20+ const mockRdfXml = '<rdf:RDF>...</rdf:RDF>'
21+ const mockEvent = { body : mockRdfXml }
2322 const mockDefaultHeaders = { 'Content-Type' : 'application/json' }
24- beforeAll ( ( ) => {
25- vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } )
26- vi . spyOn ( console , 'log' ) . mockImplementation ( ( ) => { } )
27- } )
23+ const mockConceptId = '123'
24+ const mockConceptIRI = `https://gcmd.earthdata.nasa.gov/kms/concept/${ mockConceptId } `
2825
2926 beforeEach ( ( ) => {
3027 vi . resetAllMocks ( )
3128 getApplicationConfig . mockReturnValue ( { defaultResponseHeaders : mockDefaultHeaders } )
29+ getConceptId . mockReturnValue ( mockConceptId )
30+ vi . spyOn ( console , 'log' ) . mockImplementation ( ( ) => { } )
31+ vi . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } )
3232 } )
3333
34- test ( 'should return 404 if concept already exists ' , async ( ) => {
35- conceptIdExists . mockResolvedValue ( true )
34+ test ( 'should handle missing body in event ' , async ( ) => {
35+ const eventWithoutBody = { }
3636
37- const result = await createConcept ( mockEvent )
37+ const result = await createConcept ( eventWithoutBody )
3838
3939 expect ( result ) . toEqual ( {
40- statusCode : 404 ,
41- body : JSON . stringify ( { message : 'Concept https://gcmd.earthdata.nasa.gov/kms/concept/123 already exists.' } ) ,
40+ statusCode : 400 ,
41+ body : JSON . stringify ( {
42+ message : 'Error creating concept' ,
43+ error : 'Missing RDF/XML data in request body'
44+ } ) ,
4245 headers : mockDefaultHeaders
4346 } )
4447 } )
4548
46- test ( 'should create concept and return 200 if concept does not exist ' , async ( ) => {
49+ test ( 'should successfully create a concept' , async ( ) => {
4750 conceptIdExists . mockResolvedValue ( false )
4851 sparqlRequest . mockResolvedValue ( { ok : true } )
4952
5053 const result = await createConcept ( mockEvent )
5154
55+ expect ( getConceptId ) . toHaveBeenCalledWith ( mockRdfXml )
56+ expect ( conceptIdExists ) . toHaveBeenCalledWith ( mockConceptIRI )
5257 expect ( sparqlRequest ) . toHaveBeenCalledWith ( {
5358 contentType : 'application/rdf+xml' ,
5459 accept : 'application/rdf+xml' ,
5560 path : '/statements' ,
5661 method : 'POST' ,
57- body : mockEvent . body
62+ body : mockRdfXml
63+ } )
64+
65+ expect ( result ) . toEqual ( {
66+ statusCode : 201 ,
67+ body : JSON . stringify ( {
68+ message : 'Successfully created concept' ,
69+ conceptId : mockConceptId
70+ } ) ,
71+ headers : mockDefaultHeaders
5872 } )
73+ } )
74+
75+ test ( 'should return 409 if concept already exists' , async ( ) => {
76+ conceptIdExists . mockResolvedValue ( true )
77+
78+ const result = await createConcept ( mockEvent )
5979
6080 expect ( result ) . toEqual ( {
61- statusCode : 200 ,
62- body : 'Successfully loaded RDF XML into RDF4J' ,
81+ statusCode : 409 ,
82+ body : JSON . stringify ( { message : `Concept ${ mockConceptIRI } already exists.` } ) ,
6383 headers : mockDefaultHeaders
6484 } )
6585 } )
6686
67- test ( 'should return 500 if sparqlRequest fails' , async ( ) => {
87+ test ( 'should handle getConceptId throwing an error' , async ( ) => {
88+ getConceptId . mockImplementation ( ( ) => {
89+ throw new Error ( 'Invalid XML' )
90+ } )
91+
92+ const result = await createConcept ( mockEvent )
93+
94+ expect ( result ) . toEqual ( {
95+ statusCode : 400 ,
96+ body : JSON . stringify ( {
97+ message : 'Error creating concept' ,
98+ error : 'Invalid XML'
99+ } ) ,
100+ headers : mockDefaultHeaders
101+ } )
102+ } )
103+
104+ test ( 'should handle missing concept ID' , async ( ) => {
105+ getConceptId . mockReturnValue ( null )
106+
107+ const result = await createConcept ( mockEvent )
108+
109+ expect ( result ) . toEqual ( {
110+ statusCode : 400 ,
111+ body : JSON . stringify ( {
112+ message : 'Error creating concept' ,
113+ error : 'Invalid or missing concept ID'
114+ } ) ,
115+ headers : mockDefaultHeaders
116+ } )
117+ } )
118+
119+ test ( 'should handle sparqlRequest failure' , async ( ) => {
68120 conceptIdExists . mockResolvedValue ( false )
69121 sparqlRequest . mockResolvedValue ( {
70122 ok : false ,
71123 status : 500 ,
72- text : ( ) => Promise . resolve ( 'Server error' )
124+ text : async ( ) => 'Internal Server Error'
125+ } )
126+
127+ const result = await createConcept ( mockEvent )
128+
129+ expect ( result ) . toEqual ( {
130+ statusCode : 400 ,
131+ body : JSON . stringify ( {
132+ message : 'Error creating concept' ,
133+ error : 'HTTP error! status: 500'
134+ } ) ,
135+ headers : mockDefaultHeaders
73136 } )
74137
138+ expect ( console . log ) . toHaveBeenCalledWith ( 'Response text:' , 'Internal Server Error' )
139+ } )
140+
141+ test ( 'should handle conceptIdExists throwing an error' , async ( ) => {
142+ conceptIdExists . mockRejectedValue ( new Error ( 'Database error' ) )
143+
75144 const result = await createConcept ( mockEvent )
76145
77146 expect ( result ) . toEqual ( {
78- statusCode : 500 ,
79- body : 'Error loading RDF XML into RDF4J' ,
147+ statusCode : 400 ,
148+ body : JSON . stringify ( {
149+ message : 'Error creating concept' ,
150+ error : 'Database error'
151+ } ) ,
80152 headers : mockDefaultHeaders
81153 } )
82154 } )
83155
84- test ( 'should return 500 if an error is thrown ' , async ( ) => {
156+ test ( 'should handle sparqlRequest throwing an error' , async ( ) => {
85157 conceptIdExists . mockResolvedValue ( false )
86158 sparqlRequest . mockRejectedValue ( new Error ( 'Network error' ) )
87159
88160 const result = await createConcept ( mockEvent )
89161
90162 expect ( result ) . toEqual ( {
91- statusCode : 500 ,
92- body : 'Error loading RDF XML into RDF4J' ,
163+ statusCode : 400 ,
164+ body : JSON . stringify ( {
165+ message : 'Error creating concept' ,
166+ error : 'Network error'
167+ } ) ,
93168 headers : mockDefaultHeaders
94169 } )
95170 } )
0 commit comments