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 10static 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 19const 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 29static 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 38static 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 47static 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 55static 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 64static 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. 75static 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. 88static 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. 99static 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. 108static 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 119TEST(ExtensionUpdateManifestTest, TestUpdateManifest) { 120 UpdateManifest parser; 121 122 // Test parsing of a number of invalid xml cases 123 EXPECT_FALSE(parser.Parse("")); 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