66import static org .apache .commons .lang3 .RandomStringUtils .randomAlphanumeric ;
77import static org .assertj .core .api .Assertions .assertThat ;
88
9+ import com .fasterxml .jackson .core .JsonProcessingException ;
910import com .fasterxml .jackson .databind .ObjectMapper ;
1011import com .fasterxml .jackson .databind .node .ArrayNode ;
1112import com .fasterxml .jackson .databind .node .ObjectNode ;
1415import com .github .tomakehurst .wiremock .matching .RequestPatternBuilder ;
1516import java .nio .file .Path ;
1617import java .util .function .Consumer ;
18+ import me .itzg .helpers .LatchingExecutionExceptionHandler ;
19+ import me .itzg .helpers .errors .InvalidParameterException ;
1720import me .itzg .helpers .json .ObjectMappers ;
1821import me .itzg .helpers .modrinth .ModrinthCommand .DownloadDependencies ;
22+ import me .itzg .helpers .modrinth .model .Project ;
23+ import me .itzg .helpers .modrinth .model .ProjectType ;
1924import org .assertj .core .api .AbstractPathAssert ;
2025import org .jetbrains .annotations .NotNull ;
2126import org .junit .jupiter .api .Test ;
@@ -108,12 +113,7 @@ void downloadsOnlyRequestedDependencyTypes(ModrinthCommand.DownloadDependencies
108113 stubVersionRequest (requiredDepProjectId , requiredVersionId , deps -> {});
109114 stubVersionRequest (optionalDepProjectId , optionalVersionId , deps -> {});
110115
111- stubFor (get (urlPathMatching ("/cdn/(.+)" ))
112- .willReturn (aResponse ()
113- .withBody ("{{request.pathSegments.[1]}}" )
114- .withTransformers ("response-template" )
115- )
116- );
116+ stubDownload ();
117117
118118 final int exitCode = new CommandLine (
119119 new ModrinthCommand ()
@@ -150,6 +150,47 @@ else if (downloadDependencies == DownloadDependencies.OPTIONAL) {
150150 }
151151 }
152152
153+ @ Test
154+ void failsWhenNoDependenciesForModLoader (@ TempDir Path tempDir ) throws JsonProcessingException {
155+ final String projectId = randomAlphanumeric (6 );
156+ final String projectSlug = randomAlphabetic (5 );
157+ final String versionId = randomAlphanumeric (6 );
158+ final String requiredDepProjectId = randomAlphanumeric (6 );
159+
160+ stubProjectBulkRequest (projectId , projectSlug );
161+
162+ stubVersionRequest (projectId , versionId , deps -> {
163+ deps .addObject ()
164+ .put ("project_id" , requiredDepProjectId )
165+ .put ("dependency_type" , "required" );
166+ });
167+ stubVersionRequestEmptyResponse (requiredDepProjectId );
168+ stubGetProject (requiredDepProjectId , new Project ().setProjectType (ProjectType .resourcepack ));
169+
170+ stubDownload ();
171+
172+ final LatchingExecutionExceptionHandler executionExceptionHandler = new LatchingExecutionExceptionHandler ();
173+
174+ final int exitCode = new CommandLine (
175+ new ModrinthCommand ()
176+ )
177+ .setExecutionExceptionHandler (executionExceptionHandler )
178+ .execute (
179+ "--api-base-url" , wm .getRuntimeInfo ().getHttpBaseUrl (),
180+ "--output-directory" , tempDir .toString (),
181+ "--game-version" , "1.21.1" ,
182+ "--loader" , "paper" ,
183+ "--projects" , projectId ,
184+ "--download-dependencies" , DownloadDependencies .REQUIRED .name ()
185+ );
186+
187+ assertThat (exitCode ).isNotEqualTo (ExitCode .OK );
188+
189+ assertThat (executionExceptionHandler .getExecutionException ())
190+ .isInstanceOf (InvalidParameterException .class )
191+ .hasCauseInstanceOf (NoFilesAvailableException .class );
192+ }
193+
153194 @ Test
154195 void errorWhenNoApplicableVersion (@ TempDir Path tempDir ) {
155196 stubFor (
@@ -325,6 +366,15 @@ private void stubProjectBulkRequest(String projectId, String projectSlug) {
325366 );
326367 }
327368
369+ private void stubGetProject (String projectIdOrSlug , Project project ) throws JsonProcessingException {
370+ stubFor (get (urlPathEqualTo ("/v2/project/" +projectIdOrSlug ))
371+ .willReturn (aResponse ()
372+ .withHeader ("Content-Type" , "application/json" )
373+ .withBody (objectMapper .writeValueAsBytes (project ))
374+ )
375+ );
376+ }
377+
328378 private void stubVersionRequest (String projectId , String versionId , Consumer <ArrayNode > depsAdder ) {
329379 final ArrayNode versionResp = objectMapper .createArrayNode ();
330380 final ObjectNode versionNode = versionResp
@@ -347,7 +397,28 @@ private void stubVersionRequest(String projectId, String versionId, Consumer<Arr
347397 .withJsonBody (versionResp )
348398 )
349399 );
400+ }
401+
402+ private void stubVersionRequestEmptyResponse (String projectId ) {
403+ final ArrayNode versionResp = objectMapper .createArrayNode ();
350404
405+ stubFor (get (urlPathEqualTo ("/v2/project/" + projectId + "/version" ))
406+ .withQueryParam ("loaders" , equalTo ("[\" paper\" ,\" spigot\" ]" ))
407+ .withQueryParam ("game_versions" , equalTo ("[\" 1.21.1\" ]" ))
408+ .willReturn (aResponse ()
409+ .withHeader ("Content-Type" , "application/json" )
410+ .withJsonBody (versionResp )
411+ )
412+ );
413+ }
414+
415+ private static void stubDownload () {
416+ stubFor (get (urlPathMatching ("/cdn/(.+)" ))
417+ .willReturn (aResponse ()
418+ .withBody ("{{request.pathSegments.[1]}}" )
419+ .withTransformers ("response-template" )
420+ )
421+ );
351422 }
352423
353424 private static void setupStubs () {
0 commit comments