xref: /aosp_15_r20/external/bazelbuild-rules_android/src/tools/ak/patch/patch_test.go (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
1// Copyright 2018 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package patch
16
17import (
18	"bufio"
19	"bytes"
20	"encoding/xml"
21	"strings"
22	"testing"
23
24	"src/common/golang/xml2"
25	"src/tools/ak/manifestutils"
26)
27
28const (
29	manifestWithAppClass = `<?xml version="1.0" ?>
30<manifest package="com.google.android.other" xmlns:android="http://schemas.android.com/apk/res/android">
31  <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="21"/>
32  <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:name="android.app.OtherApplication" android:label="@string/app_name" android:theme="@style/AppTheme">
33    <activity android:label="@string/app_name" android:name="com.google.android.test.Activity">
34      <intent-filter>
35        <action android:name="android.intent.action.MAIN"/>
36        <category android:name="android.intent.category.LAUNCHER"/>
37      </intent-filter>
38    </activity>
39  </application>
40</manifest>`
41
42	manifestWithAppClassAtEnd = `<?xml version="1.0" ?>
43<manifest package="com.google.android.end" xmlns:android="http://schemas.android.com/apk/res/android">
44  <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="21"/>
45  <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" android:name="android.app.EndApplication">
46    <activity android:label="@string/app_name" android:name="com.google.android.test.Activity">
47      <intent-filter>
48        <action android:name="android.intent.action.MAIN"/>
49        <category android:name="android.intent.category.LAUNCHER"/>
50      </intent-filter>
51    </activity>
52  </application>
53</manifest>`
54
55	manifestWithNoAppClass = `<?xml version="1.0" ?>
56<manifest package="com.google.android.test" xmlns:android="http://schemas.android.com/apk/res/android">
57  <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="21"/>
58  <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme">
59    <activity android:label="@string/app_name" android:name="com.google.android.test.Activity">
60      <intent-filter>
61        <action android:name="android.intent.action.MAIN"/>
62        <category android:name="android.intent.category.LAUNCHER"/>
63      </intent-filter>
64    </activity>
65  </application>
66</manifest>`
67)
68
69func TestParsing(t *testing.T) {
70	tests := []struct {
71		name        string
72		manifestXML string
73		wantPkg     string
74		wantApp     string
75	}{
76		{
77			name:        "withAppClass",
78			manifestXML: manifestWithAppClass,
79			wantPkg:     "com.google.android.other",
80			wantApp:     "android.app.OtherApplication",
81		},
82		{
83			name:        "withAppClassAtEnd",
84			manifestXML: manifestWithAppClassAtEnd,
85			wantPkg:     "com.google.android.end",
86			wantApp:     "android.app.EndApplication",
87		},
88		{
89			name:        "noAppClass",
90			manifestXML: manifestWithNoAppClass,
91			wantPkg:     "com.google.android.test",
92			wantApp:     "",
93		},
94	}
95	for _, test := range tests {
96		t.Run(test.name, func(t *testing.T) {
97			var manifest manifestutils.Manifest
98			xml.Unmarshal([]byte(test.manifestXML), &manifest)
99			if manifest.Package != test.wantPkg {
100				t.Errorf("Parsed package name not correct: got: %q wanted: %q", manifest.Package, test.wantPkg)
101			}
102			if manifest.Application.Name != test.wantApp {
103				t.Errorf("Parsed application class name not correct: got: %q wanted: %q", manifest.Application.Name, test.wantApp)
104			}
105		})
106	}
107}
108
109func TestSetAppName(t *testing.T) {
110	tests := []struct {
111		name            string
112		manifestXML     string
113		newApp          string
114		wantManifestXML string
115	}{
116		{
117			name:        "withAppClass",
118			manifestXML: manifestWithAppClass,
119			newApp:      "android.app.OtherTestApplication",
120		},
121		{
122			name:        "withAppClassAtEnd",
123			manifestXML: manifestWithAppClassAtEnd,
124			newApp:      "android.app.EndTestApplication",
125		},
126		{
127			name:        "noAppClass",
128			manifestXML: manifestWithNoAppClass,
129			newApp:      "android.app.TestApplication",
130		},
131	}
132	elems := map[string]map[string]xml.Attr{"application": make(map[string]xml.Attr)}
133	for _, test := range tests {
134		t.Run(test.name, func(t *testing.T) {
135			elems["application"]["name"] = xml.Attr{
136				Name: xml.Name{Space: manifestutils.NameSpace, Local: "name"}, Value: test.newApp}
137			var b bytes.Buffer
138			e := xml2.NewEncoder(bufio.NewWriter(&b))
139			manifestutils.Patch(xml.NewDecoder(strings.NewReader(test.manifestXML)), e, elems)
140			if err := e.Flush(); err != nil {
141				t.Fatalf("Error occurred during encoder flush: %v", err)
142			}
143			var manifest manifestutils.Manifest
144			xml.Unmarshal([]byte(b.String()), &manifest)
145			if manifest.Application.Name != test.newApp {
146				t.Errorf("New application class name not correct: got: %q wanted: %q", manifest.Application.Name, test.newApp)
147			}
148		})
149	}
150}
151
152func TestSetAppName_xmlEncoding(t *testing.T) {
153	wantManifestXML := `<?xml version="1.0" ?>
154<manifest package="com.google.android.other" xmlns:android="http://schemas.android.com/apk/res/android">
155  <uses-sdk android:minSdkVersion="10" android:targetSdkVersion="21"></uses-sdk>
156  <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:name="android.app.OtherApplication" android:label="@string/app_name" android:theme="@style/AppTheme">
157    <activity android:label="@string/app_name" android:name="com.google.android.test.Activity">
158      <intent-filter>
159        <action android:name="android.intent.action.MAIN"></action>
160        <category android:name="android.intent.category.LAUNCHER"></category>
161      </intent-filter>
162    </activity>
163  </application>
164</manifest>`
165
166	elems := map[string]map[string]xml.Attr{
167		"application": map[string]xml.Attr{"name": xml.Attr{
168			Name: xml.Name{Space: manifestutils.NameSpace, Local: "name"}, Value: "android.app.OtherApplication"}}}
169	var b bytes.Buffer
170	e := xml2.NewEncoder(bufio.NewWriter(&b))
171	manifestutils.Patch(xml.NewDecoder(strings.NewReader(manifestWithAppClass)), e, elems)
172	if err := e.Flush(); err != nil {
173		t.Fatalf("Error occurred during encoder flush: %v", err)
174	}
175	if b.String() != wantManifestXML {
176		t.Errorf("got: <%s> expected: <%s>", b.String(), wantManifestXML)
177	}
178}
179