1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.adservices.common;
18 
19 import android.net.Uri;
20 import android.os.Parcel;
21 
22 import com.android.adservices.AdServicesParcelableUtil;
23 import com.android.adservices.common.JsonFixture;
24 
25 import com.google.common.collect.ImmutableList;
26 import com.google.common.collect.ImmutableSet;
27 
28 import org.json.JSONException;
29 
30 import java.util.List;
31 
32 /** Utility class supporting ad services API unit tests */
33 public class AdDataFixture {
34     public static final String VALID_METADATA = "{\"example\": \"metadata\", \"valid\": true}";
35     public static final String INVALID_METADATA = "not.{real!metadata} = 1";
36 
37     public static final String VALID_RENDER_ID = "render-id";
38     public static final String INVALID_RENDER_ID =
39             "this is a very very very very very long render-id";
40 
getAdCounterKeys()41     public static ImmutableSet<Integer> getAdCounterKeys() {
42         return ImmutableSet.<Integer>builder()
43                 .add(
44                         KeyedFrequencyCapFixture.KEY1,
45                         KeyedFrequencyCapFixture.KEY2,
46                         KeyedFrequencyCapFixture.KEY3,
47                         KeyedFrequencyCapFixture.KEY4)
48                 .build();
49     }
50 
getExcessiveNumberOfAdCounterKeys()51     public static ImmutableSet<Integer> getExcessiveNumberOfAdCounterKeys() {
52         ImmutableSet.Builder<Integer> setBuilder = ImmutableSet.builder();
53 
54         // Add just one more than the limit
55         for (int key = 0; key <= AdData.MAX_NUM_AD_COUNTER_KEYS; key++) {
56             setBuilder.add(key);
57         }
58 
59         return setBuilder.build();
60     }
61 
getValidRenderUriByBuyer(AdTechIdentifier buyer, int sequence)62     public static Uri getValidRenderUriByBuyer(AdTechIdentifier buyer, int sequence) {
63         return CommonFixture.getUri(buyer, "/testing/hello" + sequence);
64     }
65 
getValidRenderUriByBuyer(AdTechIdentifier buyer, String sequence)66     public static Uri getValidRenderUriByBuyer(AdTechIdentifier buyer, String sequence) {
67         return CommonFixture.getUri(buyer, "/testing/hello" + sequence);
68     }
69 
getValidAdsByBuyer(AdTechIdentifier buyer)70     public static List<AdData> getValidAdsByBuyer(AdTechIdentifier buyer) {
71         return ImmutableList.of(
72                 getValidAdDataByBuyer(buyer, 1),
73                 getValidAdDataByBuyer(buyer, 2),
74                 getValidAdDataByBuyer(buyer, 3),
75                 getValidAdDataByBuyer(buyer, 4));
76     }
77 
78     // TODO(b/266837113) Merge with getValidAdsByBuyer once filters are unhidden
getValidFilterAdsByBuyer(AdTechIdentifier buyer)79     public static List<AdData> getValidFilterAdsByBuyer(AdTechIdentifier buyer) {
80         return ImmutableList.of(
81                 getValidFilterAdDataByBuyer(buyer, 1),
82                 getValidFilterAdDataByBuyer(buyer, 2),
83                 getValidAdDataByBuyer(buyer, 3),
84                 getValidAdDataByBuyer(buyer, 4));
85     }
86 
getValidFilterAdsWithAdRenderIdByBuyer(AdTechIdentifier buyer)87     public static List<AdData> getValidFilterAdsWithAdRenderIdByBuyer(AdTechIdentifier buyer) {
88         return ImmutableList.of(
89                 getValidFilterAdDataWithAdRenderIdByBuyer(buyer, 1),
90                 getValidFilterAdDataWithAdRenderIdByBuyer(buyer, 2),
91                 getValidFilterAdDataByBuyer(buyer, 3),
92                 getValidFilterAdDataByBuyer(buyer, 4),
93                 getValidAdDataByBuyer(buyer, 5),
94                 getValidAdDataByBuyer(buyer, 6));
95     }
96 
97     /** Returns a list AdData with invalid render IDs */
getValidFilterAdsWithInvalidAdRenderIdByBuyer( AdTechIdentifier buyer)98     public static List<AdData> getValidFilterAdsWithInvalidAdRenderIdByBuyer(
99             AdTechIdentifier buyer) {
100         return ImmutableList.of(
101                 getValidFilterAdDataWithAdRenderIdByBuyer(buyer, INVALID_RENDER_ID + "1"),
102                 getValidFilterAdDataWithAdRenderIdByBuyer(buyer, INVALID_RENDER_ID + "2"));
103     }
104 
getInvalidAdsByBuyer(AdTechIdentifier buyer)105     public static List<AdData> getInvalidAdsByBuyer(AdTechIdentifier buyer) {
106         return ImmutableList.of(
107                 new AdData.Builder()
108                         .setRenderUri(getValidRenderUriByBuyer(buyer, 1))
109                         .setMetadata(INVALID_METADATA)
110                         .build(),
111                 new AdData.Builder()
112                         .setRenderUri(getValidRenderUriByBuyer(buyer, 2))
113                         .setMetadata(INVALID_METADATA)
114                         .build(),
115                 new AdData.Builder()
116                         .setRenderUri(getValidRenderUriByBuyer(buyer, 3))
117                         .setMetadata(INVALID_METADATA)
118                         .build(),
119                 new AdData.Builder()
120                         .setRenderUri(getValidRenderUriByBuyer(buyer, 4))
121                         .setMetadata(INVALID_METADATA)
122                         .build());
123     }
124 
getValidAdDataBuilderByBuyer( AdTechIdentifier buyer, int sequenceNumber)125     public static AdData.Builder getValidAdDataBuilderByBuyer(
126             AdTechIdentifier buyer, int sequenceNumber) {
127         String metadata;
128         try {
129             metadata = JsonFixture.formatAsOrgJsonJSONObjectString(VALID_METADATA);
130         } catch (JSONException exception) {
131             throw new IllegalStateException("Error parsing valid metadata!", exception);
132         }
133 
134         return new AdData.Builder()
135                 .setRenderUri(getValidRenderUriByBuyer(buyer, sequenceNumber))
136                 .setMetadata(metadata);
137     }
138 
getValidAdDataWithSubdomainBuilderByBuyer( AdTechIdentifier buyer, int sequenceNumber)139     public static AdData.Builder getValidAdDataWithSubdomainBuilderByBuyer(
140             AdTechIdentifier buyer, int sequenceNumber) {
141         return getValidAdDataBuilderByBuyer(buyer, sequenceNumber)
142                 .setRenderUri(
143                         CommonFixture.getUriWithValidSubdomain(
144                                 buyer.toString(), "/testing/hello" + sequenceNumber));
145     }
146 
147     // TODO(b/266837113) Merge with getValidAdDataByBuyer once filters are unhidden
getValidFilterAdDataBuilderByBuyer( AdTechIdentifier buyer, int sequenceNumber)148     public static AdData.Builder getValidFilterAdDataBuilderByBuyer(
149             AdTechIdentifier buyer, int sequenceNumber) {
150         return getValidAdDataBuilderByBuyer(buyer, sequenceNumber)
151                 .setAdCounterKeys(getAdCounterKeys())
152                 .setAdFilters(AdFiltersFixture.getValidAdFilters());
153     }
154 
155     // TODO(b/266837113) Merge with getValidAdDataByBuyer once filters are unhidden
getValidFilterAdDataByBuyer(AdTechIdentifier buyer, int sequenceNumber)156     public static AdData getValidFilterAdDataByBuyer(AdTechIdentifier buyer, int sequenceNumber) {
157         return getValidFilterAdDataBuilderByBuyer(buyer, sequenceNumber).build();
158     }
159 
160     // TODO(b/266837113) Merge with getValidAdDataByBuyer once filters are unhidden
getValidFilterAdDataWithAdRenderIdByBuyer( AdTechIdentifier buyer, int sequenceNumber)161     public static AdData getValidFilterAdDataWithAdRenderIdByBuyer(
162             AdTechIdentifier buyer, int sequenceNumber) {
163         return getValidFilterAdDataBuilderByBuyer(buyer, sequenceNumber)
164                 .setAdRenderId(String.valueOf(sequenceNumber))
165                 .build();
166     }
167 
getValidFilterAdDataWithAdRenderIdByBuyer( AdTechIdentifier buyer, String sequenceString)168     public static AdData getValidFilterAdDataWithAdRenderIdByBuyer(
169             AdTechIdentifier buyer, String sequenceString) {
170 
171         String metadata;
172         try {
173             metadata = JsonFixture.formatAsOrgJsonJSONObjectString(VALID_METADATA);
174         } catch (JSONException exception) {
175             throw new IllegalStateException("Error parsing valid metadata!", exception);
176         }
177 
178         return new AdData.Builder()
179                 .setRenderUri(getValidRenderUriByBuyer(buyer, sequenceString))
180                 .setMetadata(metadata)
181                 .setAdCounterKeys(getAdCounterKeys())
182                 .setAdFilters(AdFiltersFixture.getValidAdFilters())
183                 .setAdRenderId(sequenceString)
184                 .build();
185     }
186 
getValidAdDataByBuyer(AdTechIdentifier buyer, int sequenceNumber)187     public static AdData getValidAdDataByBuyer(AdTechIdentifier buyer, int sequenceNumber) {
188         return getValidAdDataBuilderByBuyer(buyer, sequenceNumber).build();
189     }
190 
getAdDataWithExceededFrequencyCapLimits( AdTechIdentifier buyer, int sequenceNumber)191     public static AdData getAdDataWithExceededFrequencyCapLimits(
192             AdTechIdentifier buyer, int sequenceNumber) {
193         AdData sourceAdData = getValidAdDataByBuyer(buyer, sequenceNumber);
194 
195         Parcel sourceParcel = Parcel.obtain();
196         sourceAdData.getRenderUri().writeToParcel(sourceParcel, 0);
197         sourceParcel.writeString(sourceAdData.getMetadata());
198         AdServicesParcelableUtil.writeNullableToParcel(
199                 sourceParcel,
200                 getExcessiveNumberOfAdCounterKeys(),
201                 AdServicesParcelableUtil::writeIntegerSetToParcel);
202         AdServicesParcelableUtil.writeNullableToParcel(
203                 sourceParcel,
204                 new AdFilters.Builder()
205                         .setFrequencyCapFilters(
206                                 FrequencyCapFiltersFixture
207                                         .getFrequencyCapFiltersWithExcessiveNumFilters())
208                         .build(),
209                 (targetParcel, sourceFilters) -> sourceFilters.writeToParcel(targetParcel, 0));
210         sourceParcel.setDataPosition(0);
211 
212         return AdData.CREATOR.createFromParcel(sourceParcel);
213     }
214 }
215