15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/update_manifest.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml/globals.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kValidXml =
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' prodversionmin='2.0.143.0' />"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *valid_xml_with_hash =
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' prodversionmin='2.0.143.0' "
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               hash='1234'/>"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char*  kMissingAppId =
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app>"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' />"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char*  kInvalidCodebase =
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345' status='ok'>"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='example.com/extension_1.2.3.4.crx'"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' />"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char*  kMissingVersion =
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345' status='ok'>"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' />"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char*  kInvalidVersion =
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0'?>"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345' status='ok'>"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' "
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.a'/>"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kUsesNamespacePrefix =
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<g:gupdate xmlns:g='http://www.google.com/update2/response' protocol='2.0'>"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <g:app appid='12345'>"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <g:updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' prodversionmin='2.0.143.0' />"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </g:app>"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</g:gupdate>";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Includes unrelated <app> tags from other xml namespaces - this should
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not cause problems.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kSimilarTagnames =
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response'"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"         xmlns:a='http://a' protocol='2.0'>"
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <a:app/>"
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <b:app xmlns:b='http://b' />"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' prodversionmin='2.0.143.0' />"
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Includes a <daystart> tag.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kWithDaystart =
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <daystart elapsed_seconds='456' />"
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>"
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"               version='1.2.3.4' prodversionmin='2.0.143.0' />"
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Indicates no updates available - this should not be a parse error.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kNoUpdate =
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='12345'>"
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck status='noupdate' />"
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Includes two <app> tags, one with an error.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const char* kTwoAppsOneError =
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<?xml version='1.0' encoding='UTF-8'?>"
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='aaaaaaaa' status='error-unknownApplication'>"
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck status='error-unknownapplication'/>"
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" <app appid='bbbbbbbb'>"
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"  <updatecheck codebase='http://example.com/b_3.1.crx' version='3.1'/>"
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)" </app>"
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"</gupdate>";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ExtensionUpdateManifestTest, TestUpdateManifest) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateManifest parser;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test parsing of a number of invalid xml cases
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_FALSE(parser.Parse(std::string()));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.errors().empty());
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kMissingAppId));
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.results().list.empty());
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.errors().empty());
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kInvalidCodebase));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.results().list.empty());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.errors().empty());
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kMissingVersion));
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.results().list.empty());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.errors().empty());
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kInvalidVersion));
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.results().list.empty());
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.errors().empty());
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse some valid XML, and check that all params came out as expected
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kValidXml));
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.errors().empty());
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.results().list.empty());
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const UpdateManifest::Result* firstResult = &parser.results().list.at(0);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(GURL("http://example.com/extension_1.2.3.4.crx"),
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            firstResult->crx_url);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1.2.3.4", firstResult->version);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("2.0.143.0", firstResult->browser_min_version);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse some xml that uses namespace prefixes.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kUsesNamespacePrefix));
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.errors().empty());
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kSimilarTagnames));
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.errors().empty());
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  xmlCleanupGlobals();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse xml with hash value
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(valid_xml_with_hash));
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.errors().empty());
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.results().list.empty());
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  firstResult = &parser.results().list.at(0);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ("1234", firstResult->package_hash);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse xml with a <daystart> element.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kWithDaystart));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.errors().empty());
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.results().list.empty());
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(parser.results().daystart_elapsed_seconds, 456);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse a no-update response.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kNoUpdate));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.errors().empty());
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.results().list.empty());
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  firstResult = &parser.results().list.at(0);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(firstResult->extension_id, "12345");
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(firstResult->version, "");
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Parse xml with one error and one success <app> tag.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(parser.Parse(kTwoAppsOneError));
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(parser.errors().empty());
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(1u, parser.results().list.size());
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  firstResult = &parser.results().list.at(0);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(firstResult->extension_id, "bbbbbbbb");
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
188