@@ -161,35 +161,48 @@ func TestValidateTypeFilterTagCodes(t *testing.T) {
161161 ctx = log .NewStructuredLoggerEntry (logrus .New (), ctx )
162162
163163 tests := []struct {
164- name string
165- url string
166- shouldFail bool
167- errMsg string
168- description string
164+ name string
165+ url string
166+ shouldFail bool
167+ errMsg string
168+ description string
169+ expectedTypeFilter [][]string // when non-nil, we assert the parsed TypeFilter in context equals this making sure params are not dropped.
169170 }{
170171 {
171172 name : "validTagSharedSystem" ,
172173 url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3F_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FSystem-Type%%7CSharedSystem" , baseV3 ),
173174 shouldFail : false ,
174175 description : "Valid tag in URL format should pass" ,
176+ expectedTypeFilter : [][]string {
177+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/System-Type|SharedSystem" },
178+ },
175179 },
176180 {
177181 name : "validTagNationalClaimsHistory" ,
178182 url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3F_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FSystem-Type%%7CNationalClaimsHistory" , baseV3 ),
179183 shouldFail : false ,
180184 description : "Valid NotFinalAction tag should pass" ,
185+ expectedTypeFilter : [][]string {
186+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/System-Type|NationalClaimsHistory" },
187+ },
181188 },
182189 {
183190 name : "validTagFinalAction" ,
184191 url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3F_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FFinal-Action%%7CFinalAction" , baseV3 ),
185192 shouldFail : false ,
186193 description : "Valid FinalAction tag should pass" ,
194+ expectedTypeFilter : [][]string {
195+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/Final-Action|FinalAction" },
196+ },
187197 },
188198 {
189199 name : "validTagNotFinalAction" ,
190200 url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3F_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FFinal-Action%%7CNotFinalAction" , baseV3 ),
191201 shouldFail : false ,
192202 description : "Valid NationalClaimsHistory tag should pass" ,
203+ expectedTypeFilter : [][]string {
204+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/Final-Action|NotFinalAction" },
205+ },
193206 },
194207 {
195208 name : "invalidTagPartiallyAdjudicated" ,
@@ -217,6 +230,31 @@ func TestValidateTypeFilterTagCodes(t *testing.T) {
217230 url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3F_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FFinal-Action%%7CNotFinalAction%%26_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FSystem-Type%%7CSharedSystem" , baseV3 ),
218231 shouldFail : false ,
219232 description : "Multiple valid tags should pass" ,
233+ expectedTypeFilter : [][]string {
234+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/Final-Action|NotFinalAction" },
235+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/System-Type|SharedSystem" },
236+ },
237+ },
238+
239+ {
240+ name : "validTypeFilterServiceDateAndTag" ,
241+ url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3Fservice-date%%3Dlt2021-02-15%%26_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FFinal-Action%%7CFinalAction" , baseV3 ),
242+ shouldFail : false ,
243+ description : "Subquery with service-date and _tag (FinalAction) should pass" ,
244+ expectedTypeFilter : [][]string {
245+ {"service-date" , "lt2021-02-15" },
246+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/Final-Action|FinalAction" },
247+ },
248+ },
249+ {
250+ name : "validTypeFilterServiceDateAndTagAlternate" ,
251+ url : fmt .Sprintf ("%s_typeFilter=ExplanationOfBenefit%%3Fservice-date%%3Dgt2001-04-01%%26_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FSystem-Type%%7CNationalClaimsHistory" , baseV3 ),
252+ shouldFail : false ,
253+ description : "Subquery with service-date and _tag (NationalClaimsHistory) should pass" ,
254+ expectedTypeFilter : [][]string {
255+ {"service-date" , "gt2001-04-01" },
256+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/System-Type|NationalClaimsHistory" },
257+ },
220258 },
221259 {
222260 name : "multipleTagsOneInvalid" ,
@@ -237,6 +275,18 @@ func TestValidateTypeFilterTagCodes(t *testing.T) {
237275 shouldFail : false ,
238276 description : "v1 should ignore _typeFilter validation (old behavior preserved)" ,
239277 },
278+
279+ {
280+ name : "multipleTypeFilterSubqueries" ,
281+ url : fmt .Sprintf ("%s_type=ExplanationOfBenefit&_typeFilter=ExplanationOfBenefit%%3Fservice-date%%3Dlt2021-02-15%%26_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FFinal-Action%%7CFinalAction&_typeFilter=ExplanationOfBenefit%%3F_tag%%3Dhttps%%3A%%2F%%2Fbluebutton.cms.gov%%2Ffhir%%2FCodeSystem%%2FFinal-Action%%7CNotFinalAction" , baseV3 ),
282+ shouldFail : false ,
283+ description : "Multiple _typeFilter params (Bulk IG OR: FinalAction EOBs before 2021-02-15 OR all NotFinalAction EOBs) should pass validation" ,
284+ expectedTypeFilter : [][]string {
285+ {"service-date" , "lt2021-02-15" },
286+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/Final-Action|FinalAction" },
287+ {"_tag" , "https://bluebutton.cms.gov/fhir/CodeSystem/Final-Action|NotFinalAction" },
288+ },
289+ },
240290 }
241291
242292 for _ , tt := range tests {
@@ -247,14 +297,25 @@ func TestValidateTypeFilterTagCodes(t *testing.T) {
247297 req .Header .Set ("Accept" , "application/fhir+json" )
248298 req .Header .Set ("Prefer" , constants .TestRespondAsync )
249299
300+ var capturedCtx context.Context
301+ handler := http .HandlerFunc (func (rw http.ResponseWriter , r * http.Request ) {
302+ capturedCtx = r .Context ()
303+ rw .WriteHeader (http .StatusOK )
304+ })
305+
250306 rr := httptest .NewRecorder ()
251- ValidateRequestURL (noop ).ServeHTTP (rr , req )
307+ ValidateRequestURL (handler ).ServeHTTP (rr , req )
252308
253309 if tt .shouldFail {
254310 assert .Equal (t , http .StatusBadRequest , rr .Code , tt .description )
255311 assert .Contains (t , rr .Body .String (), tt .errMsg , tt .description )
256312 } else {
257313 assert .Equal (t , http .StatusOK , rr .Code , tt .description )
314+ if tt .expectedTypeFilter != nil {
315+ rp , ok := GetRequestParamsFromCtx (capturedCtx )
316+ assert .True (t , ok , "request params should be in context" )
317+ assert .Equal (t , tt .expectedTypeFilter , rp .TypeFilter , "parsed _typeFilter params should match request" )
318+ }
258319 }
259320 })
260321 }
0 commit comments