chromium/chrome/browser/ash/smb_client/smb_url_unittest.cc

// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/smb_client/smb_url.h"

#include <string>

#include "chrome/browser/ash/smb_client/smb_constants.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ash::smb_client {

class SmbUrlTest : public testing::Test {
 public:
  SmbUrlTest() = default;
  SmbUrlTest(const SmbUrlTest&) = delete;
  SmbUrlTest& operator=(const SmbUrlTest&) = delete;
  ~SmbUrlTest() override = default;

  void ExpectInvalidUrl(const std::string& url) {
    SmbUrl smb_url(url);
    EXPECT_FALSE(smb_url.IsValid());
  }

  void ExpectValidUrl(const std::string& url,
                      const std::string& expected_url,
                      const std::string& expected_host,
                      const std::string& expected_share) {
    SmbUrl smb_url(url);
    EXPECT_TRUE(smb_url.IsValid());
    EXPECT_EQ(expected_url, smb_url.ToString());
    EXPECT_EQ(expected_host, smb_url.GetHost());
    EXPECT_EQ(expected_share, smb_url.GetShare());
  }

  void ExpectValidWindowsUNC(const std::string& url,
                             const std::string& expected_unc) {
    SmbUrl smb_url(url);
    EXPECT_TRUE(smb_url.IsValid());
    EXPECT_EQ(expected_unc, smb_url.GetWindowsUNCString());
  }
};

TEST_F(SmbUrlTest, EmptyUrlIsInvalid) {
  ExpectInvalidUrl("");
}

TEST_F(SmbUrlTest, InvalidUrls) {
  ExpectInvalidUrl("smb");
  ExpectInvalidUrl("smb://");
  ExpectInvalidUrl("\\");
  ExpectInvalidUrl("\\\\");
  ExpectInvalidUrl("smb:///");
  ExpectInvalidUrl("://host/path");
  ExpectInvalidUrl("\\://host/path");
  ExpectInvalidUrl("\\:/host/path");
}

TEST_F(SmbUrlTest, ValidHappyPathUrls) {
  ExpectValidUrl("smb://x", "smb://x", "x", "");
  ExpectValidUrl("\\\\x", "smb://x", "x", "");
  ExpectValidUrl("smb://x/", "smb://x", "x", "");
  ExpectValidUrl("\\\\x\\", "smb://x", "x", "");

  ExpectValidUrl("smb://x/share", "smb://x/share", "x", "share");
  ExpectValidUrl("\\\\x\\share", "smb://x/share", "x", "share");
  ExpectValidUrl("smb://x/share/", "smb://x/share", "x", "share");
  ExpectValidUrl("\\\\x\\share\\", "smb://x/share", "x", "share");

  // Double forward slash is not removed (except if trailing) and
  // results in an empty share if used immediately after the host.
  ExpectValidUrl("smb://x//path", "smb://x//path", "x", "");
  ExpectValidUrl("\\\\x\\\\path", "smb://x//path", "x", "");
  ExpectValidUrl("smb://x//path//long", "smb://x//path//long", "x", "");
  ExpectValidUrl("\\\\x\\\\path\\\\long", "smb://x//path//long", "x", "");
  ExpectValidUrl("smb://x//path//long//longer", "smb://x//path//long//longer",
                 "x", "");
  ExpectValidUrl("\\\\x\\\\path\\\\long\\\\longer",
                 "smb://x//path//long//longer", "x", "");

  ExpectValidUrl("smb://x/share/path", "smb://x/share/path", "x", "share");
  ExpectValidUrl("\\\\x\\share\\path", "smb://x/share/path", "x", "share");
  ExpectValidUrl("smb://x/share/path/", "smb://x/share/path", "x", "share");
  ExpectValidUrl("\\\\x\\share\\path\\", "smb://x/share/path", "x", "share");

  ExpectValidUrl("smb://x/share/long/folder", "smb://x/share/long/folder", "x",
                 "share");
  ExpectValidUrl("\\\\x\\share\\long\\folder", "smb://x/share/long/folder", "x",
                 "share");
  ExpectValidUrl("smb://x/share/folder.with.dots",
                 "smb://x/share/folder.with.dots", "x", "share");
  ExpectValidUrl("\\\\x\\share\\folder.with.dots",
                 "smb://x/share/folder.with.dots", "x", "share");

  ExpectValidUrl("smb://192.168.0.1/share", "smb://192.168.0.1/share",
                 "192.168.0.1", "share");
  ExpectValidUrl("\\\\192.168.0.1\\share", "smb://192.168.0.1/share",
                 "192.168.0.1", "share");
}

TEST_F(SmbUrlTest, ValidWeirdSlashUrls) {
  ExpectValidUrl("smb://x/share\\", "smb://x/share", "x", "share");
  ExpectValidUrl("smb://x/share\\\\", "smb://x/share", "x", "share");
  ExpectValidUrl("smb://x/share//", "smb://x/share", "x", "share");

  ExpectValidUrl("smb://x\\share/mixed\\slashes", "smb://x/share/mixed/slashes",
                 "x", "share");
  ExpectValidUrl("\\\\x\\share/mixed\\slashes", "smb://x/share/mixed/slashes",
                 "x", "share");

  ExpectValidUrl("smb:///x", "smb://x", "x", "");
  ExpectValidUrl("smb:///x/", "smb://x", "x", "");

  ExpectValidUrl("smb:///x/share", "smb://x/share", "x", "share");
  ExpectValidUrl("smb:///x/share/", "smb://x/share", "x", "share");

  ExpectValidUrl("smb:///x//path", "smb://x//path", "x", "");
  ExpectValidUrl("smb:///x//path//", "smb://x//path", "x", "");

  ExpectValidUrl("smb:///x//path//long", "smb://x//path//long", "x", "");
  ExpectValidUrl("smb:///x//path//long//", "smb://x//path//long", "x", "");
}

TEST_F(SmbUrlTest, TrimTrailingSlashes) {
  ExpectValidUrl("smb://x/", "smb://x", "x", "");
  ExpectValidUrl("\\\\x\\", "smb://x", "x", "");
  ExpectValidUrl("\\\\x//", "smb://x", "x", "");

  ExpectValidUrl("smb://x//", "smb://x", "x", "");
  ExpectValidUrl("\\\\x\\\\", "smb://x", "x", "");
  ExpectValidUrl("\\\\x////", "smb://x", "x", "");

  ExpectValidUrl("smb://x/share/", "smb://x/share", "x", "share");
  ExpectValidUrl("\\\\x\\share\\", "smb://x/share", "x", "share");
  ExpectValidUrl("\\\\x\\share//", "smb://x/share", "x", "share");

  ExpectValidUrl("smb://x/share//", "smb://x/share", "x", "share");
  ExpectValidUrl("\\\\x\\share\\\\", "smb://x/share", "x", "share");
  ExpectValidUrl("\\\\x\\share////", "smb://x/share", "x", "share");

  ExpectValidUrl("smb://x/share/path/", "smb://x/share/path", "x", "share");
  ExpectValidUrl("\\\\x\\share\\path\\", "smb://x/share/path", "x", "share");
  ExpectValidUrl("\\\\x\\share\\path//", "smb://x/share/path", "x", "share");

  ExpectValidUrl("smb://x/share/path//", "smb://x/share/path", "x", "share");
  ExpectValidUrl("\\\\x\\share\\path\\\\", "smb://x/share/path", "x", "share");
  ExpectValidUrl("\\\\x\\share\\path////", "smb://x/share/path", "x", "share");

  // Double slash after host (only) is not removed and results in an
  // empty share.
  ExpectValidUrl("smb://x//path//", "smb://x//path", "x", "");
  ExpectValidUrl("\\\\x\\\\path\\\\", "smb://x//path", "x", "");
  ExpectValidUrl("smb://x//path//long//", "smb://x//path//long", "x", "");
  ExpectValidUrl("\\\\x\\\\path\\\\long\\\\", "smb://x//path//long", "x", "");
  ExpectValidUrl("smb://x//path//long//longer\\", "smb://x//path//long//longer",
                 "x", "");
  ExpectValidUrl("\\\\x\\\\path\\\\long\\\\longer\\\\",
                 "smb://x//path//long//longer", "x", "");
}

TEST_F(SmbUrlTest, NotValidIfStartsWithoutSchemeOrDoubleBackslash) {
  ExpectInvalidUrl("192.168.0.1/share");
}

TEST_F(SmbUrlTest, StartsWithBackslashRemovesBackslashAndAddsScheme) {
  ExpectValidUrl("\\\\192.168.0.1\\share", "smb://192.168.0.1/share",
                 "192.168.0.1", "share");
}

TEST_F(SmbUrlTest, GetHostWithIp) {
  ExpectValidUrl("smb://192.168.0.1/share", "smb://192.168.0.1/share",
                 "192.168.0.1", "share");
}

TEST_F(SmbUrlTest, GetHostWithDomain) {
  ExpectValidUrl("smb://server/share", "smb://server/share", "server", "share");
}

TEST_F(SmbUrlTest, HostBecomesLowerCase) {
  ExpectValidUrl("smb://SERVER/share", "smb://server/share", "server", "share");
}

TEST_F(SmbUrlTest, ReplacesHost) {
  SmbUrl smb_url("smb://server/share");
  EXPECT_TRUE(smb_url.IsValid());

  const std::string expected_host = "server";
  EXPECT_EQ(expected_host, smb_url.GetHost());

  const std::string new_host = "192.168.0.1";
  const std::string expected_url = "smb://192.168.0.1/share";
  EXPECT_EQ(expected_url, smb_url.ReplaceHost(new_host).ToString());

  // GetHost returns the original host.
  EXPECT_EQ(expected_host, smb_url.GetHost());
}

TEST_F(SmbUrlTest, GetWindowsURL) {
  ExpectValidWindowsUNC("smb://server/share", "\\\\server\\share");
  ExpectValidWindowsUNC("smb://server/share/long/folder",
                        "\\\\server\\share\\long\\folder");
  ExpectValidWindowsUNC("smb://server/share/folder.with.dots",
                        "\\\\server\\share\\folder.with.dots");
  ExpectValidWindowsUNC("smb://server\\share/mixed\\slashes",
                        "\\\\server\\share\\mixed\\slashes");
  ExpectValidWindowsUNC("\\\\server/share", "\\\\server\\share");
}

}  // namespace ash::smb_client