Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/memory/scoped_vector.h"
      6 #include "chrome/common/extensions/update_manifest.h"
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 #include "libxml/globals.h"
      9 
     10 static const char* kValidXml =
     11 "<?xml version='1.0' encoding='UTF-8'?>"
     12 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     13 " <app appid='12345'>"
     14 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     15 "               version='1.2.3.4' prodversionmin='2.0.143.0' />"
     16 " </app>"
     17 "</gupdate>";
     18 
     19 const char *valid_xml_with_hash =
     20 "<?xml version='1.0' encoding='UTF-8'?>"
     21 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     22 " <app appid='12345'>"
     23 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     24 "               version='1.2.3.4' prodversionmin='2.0.143.0' "
     25 "               hash='1234'/>"
     26 " </app>"
     27 "</gupdate>";
     28 
     29 static const char*  kMissingAppId =
     30 "<?xml version='1.0'?>"
     31 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     32 " <app>"
     33 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     34 "               version='1.2.3.4' />"
     35 " </app>"
     36 "</gupdate>";
     37 
     38 static const char*  kInvalidCodebase =
     39 "<?xml version='1.0'?>"
     40 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     41 " <app appid='12345' status='ok'>"
     42 "  <updatecheck codebase='example.com/extension_1.2.3.4.crx'"
     43 "               version='1.2.3.4' />"
     44 " </app>"
     45 "</gupdate>";
     46 
     47 static const char*  kMissingVersion =
     48 "<?xml version='1.0'?>"
     49 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     50 " <app appid='12345' status='ok'>"
     51 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' />"
     52 " </app>"
     53 "</gupdate>";
     54 
     55 static const char*  kInvalidVersion =
     56 "<?xml version='1.0'?>"
     57 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     58 " <app appid='12345' status='ok'>"
     59 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx' "
     60 "               version='1.2.3.a'/>"
     61 " </app>"
     62 "</gupdate>";
     63 
     64 static const char* kUsesNamespacePrefix =
     65 "<?xml version='1.0' encoding='UTF-8'?>"
     66 "<g:gupdate xmlns:g='http://www.google.com/update2/response' protocol='2.0'>"
     67 " <g:app appid='12345'>"
     68 "  <g:updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     69 "               version='1.2.3.4' prodversionmin='2.0.143.0' />"
     70 " </g:app>"
     71 "</g:gupdate>";
     72 
     73 // Includes unrelated <app> tags from other xml namespaces - this should
     74 // not cause problems.
     75 static const char* kSimilarTagnames =
     76 "<?xml version='1.0' encoding='UTF-8'?>"
     77 "<gupdate xmlns='http://www.google.com/update2/response'"
     78 "         xmlns:a='http://a' protocol='2.0'>"
     79 " <a:app/>"
     80 " <b:app xmlns:b='http://b' />"
     81 " <app appid='12345'>"
     82 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     83 "               version='1.2.3.4' prodversionmin='2.0.143.0' />"
     84 " </app>"
     85 "</gupdate>";
     86 
     87 // Includes a <daystart> tag.
     88 static const char* kWithDaystart =
     89 "<?xml version='1.0' encoding='UTF-8'?>"
     90 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
     91 " <daystart elapsed_seconds='456' />"
     92 " <app appid='12345'>"
     93 "  <updatecheck codebase='http://example.com/extension_1.2.3.4.crx'"
     94 "               version='1.2.3.4' prodversionmin='2.0.143.0' />"
     95 " </app>"
     96 "</gupdate>";
     97 
     98 // Indicates no updates available - this should not be a parse error.
     99 static const char* kNoUpdate =
    100 "<?xml version='1.0' encoding='UTF-8'?>"
    101 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
    102 " <app appid='12345'>"
    103 "  <updatecheck status='noupdate' />"
    104 " </app>"
    105 "</gupdate>";
    106 
    107 // Includes two <app> tags, one with an error.
    108 static const char* kTwoAppsOneError =
    109 "<?xml version='1.0' encoding='UTF-8'?>"
    110 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>"
    111 " <app appid='aaaaaaaa' status='error-unknownApplication'>"
    112 "  <updatecheck status='error-unknownapplication'/>"
    113 " </app>"
    114 " <app appid='bbbbbbbb'>"
    115 "  <updatecheck codebase='http://example.com/b_3.1.crx' version='3.1'/>"
    116 " </app>"
    117 "</gupdate>";
    118 
    119 TEST(ExtensionUpdateManifestTest, TestUpdateManifest) {
    120   UpdateManifest parser;
    121 
    122   // Test parsing of a number of invalid xml cases
    123   EXPECT_FALSE(parser.Parse(std::string()));
    124   EXPECT_FALSE(parser.errors().empty());
    125 
    126   EXPECT_TRUE(parser.Parse(kMissingAppId));
    127   EXPECT_TRUE(parser.results().list.empty());
    128   EXPECT_FALSE(parser.errors().empty());
    129 
    130   EXPECT_TRUE(parser.Parse(kInvalidCodebase));
    131   EXPECT_TRUE(parser.results().list.empty());
    132   EXPECT_FALSE(parser.errors().empty());
    133 
    134   EXPECT_TRUE(parser.Parse(kMissingVersion));
    135   EXPECT_TRUE(parser.results().list.empty());
    136   EXPECT_FALSE(parser.errors().empty());
    137 
    138   EXPECT_TRUE(parser.Parse(kInvalidVersion));
    139   EXPECT_TRUE(parser.results().list.empty());
    140   EXPECT_FALSE(parser.errors().empty());
    141 
    142   // Parse some valid XML, and check that all params came out as expected
    143   EXPECT_TRUE(parser.Parse(kValidXml));
    144   EXPECT_TRUE(parser.errors().empty());
    145   EXPECT_FALSE(parser.results().list.empty());
    146   const UpdateManifest::Result* firstResult = &parser.results().list.at(0);
    147   EXPECT_EQ(GURL("http://example.com/extension_1.2.3.4.crx"),
    148             firstResult->crx_url);
    149 
    150   EXPECT_EQ("1.2.3.4", firstResult->version);
    151   EXPECT_EQ("2.0.143.0", firstResult->browser_min_version);
    152 
    153   // Parse some xml that uses namespace prefixes.
    154   EXPECT_TRUE(parser.Parse(kUsesNamespacePrefix));
    155   EXPECT_TRUE(parser.errors().empty());
    156   EXPECT_TRUE(parser.Parse(kSimilarTagnames));
    157   EXPECT_TRUE(parser.errors().empty());
    158   xmlCleanupGlobals();
    159 
    160   // Parse xml with hash value
    161   EXPECT_TRUE(parser.Parse(valid_xml_with_hash));
    162   EXPECT_TRUE(parser.errors().empty());
    163   EXPECT_FALSE(parser.results().list.empty());
    164   firstResult = &parser.results().list.at(0);
    165   EXPECT_EQ("1234", firstResult->package_hash);
    166 
    167   // Parse xml with a <daystart> element.
    168   EXPECT_TRUE(parser.Parse(kWithDaystart));
    169   EXPECT_TRUE(parser.errors().empty());
    170   EXPECT_FALSE(parser.results().list.empty());
    171   EXPECT_EQ(parser.results().daystart_elapsed_seconds, 456);
    172 
    173   // Parse a no-update response.
    174   EXPECT_TRUE(parser.Parse(kNoUpdate));
    175   EXPECT_TRUE(parser.errors().empty());
    176   EXPECT_FALSE(parser.results().list.empty());
    177   firstResult = &parser.results().list.at(0);
    178   EXPECT_EQ(firstResult->extension_id, "12345");
    179   EXPECT_EQ(firstResult->version, "");
    180 
    181   // Parse xml with one error and one success <app> tag.
    182   EXPECT_TRUE(parser.Parse(kTwoAppsOneError));
    183   EXPECT_FALSE(parser.errors().empty());
    184   EXPECT_EQ(1u, parser.results().list.size());
    185   firstResult = &parser.results().list.at(0);
    186   EXPECT_EQ(firstResult->extension_id, "bbbbbbbb");
    187 }
    188