code: // Licensed to the Software Freedom Conservancy (SFC) under one
  // or more contributor license agreements.  See the NOTICE file
  // distributed with this work for additional information
  // regarding copyright ownership.  The SFC licenses this file
  // to you under the Apache License, Version 2.0 (the
  // "License"); you may not use this file except in compliance
  // with the License.  You may obtain a copy of the License at
  //
  //   http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing,
  // software distributed under the License is distributed on an
  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  // KIND, either express or implied.  See the License for the
  // specific language governing permissions and limitations
  // under the License.
  
  package org.openqa.selenium.grid.web;
  
  import static java.net.HttpURLConnection.HTTP_MOVED_TEMP;
  import static java.net.HttpURLConnection.HTTP_OK;
  import static java.nio.charset.StandardCharsets.UTF_8;
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.openqa.selenium.remote.http.HttpMethod.GET;
  
  import java.io.File;
  import java.io.IOException;
  import java.nio.file.Files;
  import java.nio.file.Path;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  import org.junit.jupiter.api.io.TempDir;
  import org.openqa.selenium.remote.http.Contents;
  import org.openqa.selenium.remote.http.HttpHandler;
  import org.openqa.selenium.remote.http.HttpRequest;
  import org.openqa.selenium.remote.http.HttpResponse;
  import org.openqa.selenium.remote.http.Route;
  
  class ResourceHandlerTest {
  
    @TempDir File folder;
    private Path base;
  
    @BeforeEach
    public void getPath() throws IOException {
      this.base = folder.toPath();
    }
  
    @Test
    void shouldLoadContent() throws IOException {
      Files.write(base.resolve("content.txt"), "I like cheese".getBytes(UTF_8));
  
      HttpHandler handler = new ResourceHandler(new PathResource(base));
      HttpResponse res = handler.execute(new HttpRequest(GET, "/content.txt"));
  
      assertThat(Contents.string(res)).isEqualTo("I like cheese");
    }
  
    @Test
    void shouldRedirectIfDirectoryButPathDoesNotEndInASlash() throws IOException {
      Path dir = base.resolve("cheese");
  
      Files.createDirectories(dir);
  
      HttpHandler handler = new ResourceHandler(new PathResource(base));
      HttpResponse res = handler.execute(new HttpRequest(GET, "/cheese"));
  
      assertThat(res.getStatus()).isEqualTo(HTTP_MOVED_TEMP);
      assertThat(res.getHeader("Location")).endsWith("/cheese/");
    }
  
    @Test
    void shouldLoadAnIndexPage() throws IOException {
      Path subdir = base.resolve("subdir");
      Files.createDirectories(subdir);
  
      Files.write(subdir.resolve("1.txt"), new byte[0]);
      Files.write(subdir.resolve("2.txt"), new byte[0]);
  
      HttpHandler handler = new ResourceHandler(new PathResource(base));
      HttpResponse res = handler.execute(new HttpRequest(GET, "/subdir/"));
  
      String text = Contents.string(res);
      assertThat(text).contains("1.txt");
      assertThat(text).contains("2.txt");
    }
  
    @Test
    void canBeNestedWithinARoute() throws IOException {
      Path contents = base.resolve("cheese").resolve("cake.txt");
  
      Files.createDirectories(contents.getParent());
      Files.write(contents, "delicious".getBytes(UTF_8));
  
      HttpHandler handler =
          Route.prefix("/peas").to(Route.combine(new ResourceHandler(new PathResource(base))));
  
      // Check redirect works as expected
      HttpResponse res = handler.execute(new HttpRequest(GET, "/peas/cheese"));
      assertThat(res.getStatus()).isEqualTo(HTTP_MOVED_TEMP);
      assertThat(res.getHeader("Location")).isEqualTo("/peas/cheese/");
  
      // And now that content can be read
      res = handler.execute(new HttpRequest(GET, "/peas/cheese/cake.txt"));
      assertThat(res.getStatus()).isEqualTo(HTTP_OK);
      assertThat(Contents.string(res)).isEqualTo("delicious");
    }
  
    @Test
    void shouldRedirectToIndexPageIfOneExists() throws IOException {
      Path index = base.resolve("index.html");
      Files.write(index, "Cheese".getBytes(UTF_8));
  
      ResourceHandler handler = new ResourceHandler(new PathResource(base));
      HttpResponse res = handler.execute(new HttpRequest(GET, "/"));
  
      assertThat(res.isSuccessful()).isTrue();
  
      String content = Contents.string(res);
      assertThat(content).isEqualTo("Cheese");
    }
  }
  