chromium/chrome/updater/win/protocol_parser_xml_unittest.cc

// Copyright 2022 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/updater/win/protocol_parser_xml.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace updater {

TEST(ProtocolParserXML, Success) {
  const char kUpdateResponse[] =
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
      "<response protocol=\"3.0\">"
      "  <systemrequirements platform=\"win\" arch=\"x64\" "
      "      min_os_version=\"6.1\"/>"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "    <updatecheck status=\"ok\">"
      "      <urls>"
      "        <url codebase=\"http://dl.google.com/edgedl/chrome/install/\"/>"
      "        <url codebase=\"http://dl.google.com/fallback/install/\"/>"
      "      </urls>"
      "      <manifest version=\"1.2.3.4\">"
      "        <packages>"
      "          <package name=\"installer.exe\" hash_sha256=\"SamPLE_SHA==\" "
      "              size=\"112233\"/>"
      "        </packages>"
      "        <actions>"
      "          <action event=\"install\" run=\"installer.exe\" "
      "              arguments=\"--do-not-launch-chrome\"/>"
      "          <action event=\"postinstall\" "
      "              onsuccess=\"exitsilentlyonlaunchcmd\"/>"
      "        </actions>"
      "      </manifest>"
      "    </updatecheck>"
      "    <data index=\"verboselogging\" name=\"install\" status=\"ok\">"
      "      {"
      "        \"distribution\": {"
      "          \"verbose_logging\": true"
      "        }"
      "      }"
      "    </data>"
      "    <data index=\"defaultbrowser\" name=\"install\" status=\"ok\">"
      "      {"
      "        \"distribution\": {"
      "          \"make_chrome_default_for_user\": true"
      "        }"
      "      }"
      "    </data>"
      "  </app>"
      "</response>";
  ProtocolParserXML xml_parser;
  EXPECT_TRUE(xml_parser.Parse(kUpdateResponse));
  EXPECT_TRUE(xml_parser.errors().empty());

  const update_client::ProtocolParser::Results& results = xml_parser.results();

  // No daystart for offline installs.
  EXPECT_EQ(results.daystart_elapsed_seconds,
            update_client::ProtocolParser::kNoDaystart);
  EXPECT_EQ(results.daystart_elapsed_days,
            update_client::ProtocolParser::kNoDaystart);
  EXPECT_EQ(results.list.size(), size_t{1});

  EXPECT_EQ(results.system_requirements.platform, "win");
  EXPECT_EQ(results.system_requirements.arch, "x64");
  EXPECT_EQ(results.system_requirements.min_os_version, "6.1");

  const update_client::ProtocolParser::Result& result = results.list[0];
  EXPECT_TRUE(result.action_run.empty());
  EXPECT_EQ(result.cohort_attrs.size(), size_t{0});
  EXPECT_EQ(result.custom_attributes.size(), size_t{0});
  EXPECT_EQ(result.crx_diffurls.size(), size_t{0});

  EXPECT_EQ(result.extension_id, "{8A69D345-D564-463C-AFF1-A69D9E530F96}");
  EXPECT_EQ(result.status, "ok");
  EXPECT_EQ(result.crx_urls.size(), size_t{2});
  EXPECT_EQ(result.crx_urls[0], "http://dl.google.com/edgedl/chrome/install/");
  EXPECT_EQ(result.crx_urls[1], "http://dl.google.com/fallback/install/");

  EXPECT_EQ(result.manifest.version, "1.2.3.4");
  EXPECT_TRUE(result.manifest.browser_min_version.empty());
  EXPECT_EQ(result.manifest.run, "installer.exe");
  EXPECT_EQ(result.manifest.arguments, "--do-not-launch-chrome");

  EXPECT_EQ(result.manifest.packages.size(), size_t{1});
  EXPECT_TRUE(result.manifest.packages[0].fingerprint.empty());
  EXPECT_EQ(result.manifest.packages[0].name, "installer.exe");
  EXPECT_EQ(result.manifest.packages[0].hash_sha256, "SamPLE_SHA==");
  EXPECT_EQ(result.manifest.packages[0].size, 112233);
  EXPECT_TRUE(result.manifest.packages[0].namediff.empty());
  EXPECT_TRUE(result.manifest.packages[0].hashdiff_sha256.empty());
  EXPECT_EQ(result.manifest.packages[0].sizediff, 0);

  EXPECT_EQ(result.data.size(), size_t{2});
  EXPECT_EQ(result.data[0].status, "ok");
  EXPECT_EQ(result.data[0].name, "install");
  EXPECT_EQ(result.data[0].install_data_index, "verboselogging");
  EXPECT_EQ(result.data[0].text,
            "{"
            "        \"distribution\": {"
            "          \"verbose_logging\": true"
            "        }"
            "      }");
  EXPECT_EQ(result.data[1].status, "ok");
  EXPECT_EQ(result.data[1].name, "install");
  EXPECT_EQ(result.data[1].install_data_index, "defaultbrowser");
  EXPECT_EQ(result.data[1].text,
            "{"
            "        \"distribution\": {"
            "          \"make_chrome_default_for_user\": true"
            "        }"
            "      }");
}

TEST(ProtocolParserXML, BadXML) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(
      xml_parser.Parse("<response protocol=\"3.0\"></App></response>"));
  EXPECT_EQ(xml_parser.errors(), "Load manifest failed: 0x1");
}

TEST(ProtocolParserXML, UnsupportedVersion) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(xml_parser.Parse(
      "<response protocol=\"3.1\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\" />"
      "</response>"));
  EXPECT_EQ(xml_parser.errors(), "Unsupported protocol version: 3.1");
}

TEST(ProtocolParserXML, ElementOutOfScope) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(xml_parser.Parse(
      "<response protocol=\"3.0\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "  </app>"
      "  <updatecheck status=\"noupdate\"></updatecheck>"
      "</response>"));
  EXPECT_EQ(xml_parser.errors(), "Unrecognized element: updatecheck");
}

TEST(ProtocolParserXML, MissingAttribute) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(xml_parser.Parse(
      "<response protocol=\"3.0\"><app status=\"ok\"></app></response>"));
  EXPECT_EQ(xml_parser.errors(), "Missing `appid` attribute in <app>");
}

TEST(ProtocolParserXML, UnrecognizedElement) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(
      xml_parser.Parse("<response protocol=\"3.0\"><unknown /></response>"));
  EXPECT_EQ(xml_parser.errors(), "Unrecognized element: unknown");
}

TEST(ProtocolParserXML, BadUrlValue) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(xml_parser.Parse(
      "<response protocol=\"3.0\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "    <updatecheck status=\"ok\">"
      "      <urls>"
      "        <url codebase=\"ht@tp://dl.google.com\"/>"
      "      </urls>"
      "    </updatecheck>"
      "  </app>"
      "</response>"));
  EXPECT_EQ(xml_parser.errors(),
            "Invalid URL codebase in <url>: ht@tp://dl.google.com");
}

TEST(ProtocolParserXML, MissingManifestVersion) {
  ProtocolParserXML xml_parser;
  EXPECT_TRUE(xml_parser.Parse(
      "<response protocol=\"3.0\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "    <updatecheck status=\"ok\">"
      "      <manifest />"
      "    </updatecheck>"
      "  </app>"
      "</response>"));
  EXPECT_TRUE(xml_parser.errors().empty());
}

TEST(ProtocolParserXML, BadManifestVersion) {
  ProtocolParserXML xml_parser;
  EXPECT_TRUE(xml_parser.Parse(
      "<response protocol=\"3.0\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "    <updatecheck status=\"ok\">"
      "      <manifest version=\"100.99.0.abc\" />"
      "    </updatecheck>"
      "  </app>"
      "</response>"));
  EXPECT_TRUE(xml_parser.errors().empty());
}

TEST(ProtocolParserXML, BadActionEvent) {
  ProtocolParserXML xml_parser;
  EXPECT_FALSE(xml_parser.Parse(
      "<response protocol=\"3.0\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "    <updatecheck status=\"ok\">"
      "      <manifest version=\"1.2.3.4\">"
      "        <actions>"
      "          <action event=\"bad_event_type\"/>"
      "        </actions>"
      "      </manifest>"
      "    </updatecheck>"
      "  </app>"
      "</response>"));
  EXPECT_EQ(xml_parser.errors(),
            "Unsupported `event` type in <action>: bad_event_type");
}

TEST(ProtocolParserXML, MulitpleActions) {
  ProtocolParserXML xml_parser;
  EXPECT_TRUE(xml_parser.Parse(
      "<response protocol=\"3.0\">"
      "  <app appid=\"{8A69D345-D564-463C-AFF1-A69D9E530F96}\" status=\"ok\">"
      "    <updatecheck status=\"ok\">"
      "      <manifest version=\"1.2.3.4\">"
      "        <actions>"
      "          <action event=\"install\" run=\"installer.exe\" "
      "              arguments=\"--do-not-launch-chrome\"/>"
      "          <action event=\"install\" run=\"installer2.exe\" "
      "              arguments=\"--do-not-launch-chrome\"/>"
      "        </actions>"
      "      </manifest>"
      "    </updatecheck>"
      "  </app>"
      "</response>"));
  EXPECT_EQ(xml_parser.results().list[0].manifest.run, "installer.exe");
}

}  // namespace updater