1 package com.atlassian.marketplace.client.impl;
2
3 import java.net.URI;
4
5 import com.atlassian.fugue.Option;
6 import com.atlassian.marketplace.client.api.Cost;
7 import com.atlassian.marketplace.client.api.HostingType;
8 import com.atlassian.marketplace.client.api.PageReader;
9 import com.atlassian.marketplace.client.api.PageReference;
10 import com.atlassian.marketplace.client.api.ProductQuery;
11 import com.atlassian.marketplace.client.api.ProductVersionSpecifier;
12 import com.atlassian.marketplace.client.api.QueryBounds;
13 import com.atlassian.marketplace.client.model.Links;
14 import com.atlassian.marketplace.client.model.ModelBuilders;
15 import com.atlassian.marketplace.client.model.Product;
16 import com.atlassian.marketplace.client.model.ProductVersion;
17 import com.atlassian.marketplace.client.util.UriBuilder;
18
19 import com.google.common.collect.ImmutableList;
20
21 import org.junit.Test;
22
23 import static com.atlassian.fugue.Option.some;
24 import static com.atlassian.marketplace.client.TestObjects.HOST_BASE;
25 import static com.atlassian.marketplace.client.TestObjects.LINKS_WITH_NEXT;
26 import static com.atlassian.marketplace.client.TestObjects.LINKS_WITH_PREV;
27 import static com.atlassian.marketplace.client.TestObjects.LINK_NEXT_URI;
28 import static com.atlassian.marketplace.client.TestObjects.LINK_PREV_URI;
29 import static com.atlassian.marketplace.client.api.ApplicationKey.JIRA;
30 import static com.atlassian.marketplace.client.impl.ClientTester.FAKE_PRODUCTS_PATH;
31 import static com.atlassian.marketplace.client.model.TestModelBuilders.product;
32 import static com.atlassian.marketplace.client.model.TestModelBuilders.productVersion;
33 import static org.hamcrest.MatcherAssert.assertThat;
34 import static org.hamcrest.Matchers.contains;
35 import static org.hamcrest.Matchers.equalTo;
36 import static org.mockito.Mockito.verify;
37
38 public class ProductsImplTest extends ApiImplTestBase
39 {
40 private static final String FAKE_PRODUCT_BY_KEY_PATH = "/fake/products/by/key/";
41 private static final Product PRODUCT_REP = product().build();
42 private static final ProductVersion PRODUCT_VER_REP = productVersion().build();
43 private static final Links PRODUCTS_LINKS = ModelBuilders.links()
44 .putTemplate("byKey", FAKE_PRODUCT_BY_KEY_PATH + "{productKey}")
45 .putTemplate("latestVersion", FAKE_PRODUCT_BY_KEY_PATH + "{productKey}/latest")
46 .putTemplate("versionByBuild", FAKE_PRODUCT_BY_KEY_PATH + "{productKey}/build/{buildNumber}")
47 .putTemplate("versionByName", FAKE_PRODUCT_BY_KEY_PATH + "{productKey}/name/{versionName}")
48 .build();
49 private static final InternalModel.Products PRODUCTS_REP =
50 InternalModel.products(PRODUCTS_LINKS, ImmutableList.of(PRODUCT_REP), 2);
51 private static final InternalModel.Products PRODUCTS_REP_WITH_NEXT =
52 InternalModel.products(LINKS_WITH_NEXT, ImmutableList.of(PRODUCT_REP), 2);
53 private static final InternalModel.Products PRODUCTS_REP_WITH_PREV =
54 InternalModel.products(LINKS_WITH_PREV, ImmutableList.of(PRODUCT_REP), 2);
55
56 @Test
57 public void getByKeyUsesProductsResource() throws Exception
58 {
59 setupProductByKeyResource(productByKeyUri("x"));
60 tester.client.products().getByKey("x", ProductQuery.any());
61
62 verify(tester.httpTransport).get(URI.create(HOST_BASE + FAKE_PRODUCTS_PATH + "?limit=0"));
63 }
64
65 @Test
66 public void getByKeyUsesProductByKeyResource() throws Exception
67 {
68 setupProductByKeyResource(productByKeyUri("x"));
69
70 assertThat(tester.client.products().getByKey("x", ProductQuery.any()),
71 contains(PRODUCT_REP));
72 }
73
74 @Test
75 public void getByKeyPassesAppKeyInQueryString() throws Exception
76 {
77 setupProductByKeyResource(productByKeyUri("x").queryParam("application", "jira"));
78
79 assertThat(tester.client.products().getByKey("x", ProductQuery.builder().application(some(JIRA)).build()),
80 contains(PRODUCT_REP));
81 }
82
83 @Test
84 public void getByKeyPassesAppBuildNumberInQueryString() throws Exception
85 {
86 setupProductByKeyResource(productByKeyUri("x").queryParam("application", "jira").queryParam("applicationBuild", "123"));
87
88 assertThat(tester.client.products().getByKey("x", ProductQuery.builder().application(some(JIRA)).appBuildNumber(some(123)).build()),
89 contains(PRODUCT_REP));
90 }
91
92 @Test
93 public void getByKeyPassesVersionFlagInQueryString() throws Exception
94 {
95 setupProductByKeyResource(productByKeyUri("x").queryParam("withVersion", "true"));
96
97 assertThat(tester.client.products().getByKey("x", ProductQuery.builder().withVersion(true).build()),
98 contains(PRODUCT_REP));
99 }
100
101 @Test
102 public void getVersionUsesProductsResource() throws Exception
103 {
104 setupProductVersionResource(latestVersionUri("x"));
105 tester.client.products().getVersion("x", ProductVersionSpecifier.latest());
106
107 verify(tester.httpTransport).get(URI.create(HOST_BASE + FAKE_PRODUCTS_PATH + "?limit=0"));
108 }
109
110 @Test
111 public void getLatestVersionUsesLatestVersionResource() throws Exception
112 {
113 setupProductVersionResource(latestVersionUri("x"));
114
115 assertThat(tester.client.products().getVersion("x", ProductVersionSpecifier.latest()),
116 contains(PRODUCT_VER_REP));
117 }
118
119 @Test
120 public void getVersionByBuildUsesVersionByBuildResource() throws Exception
121 {
122 setupProductVersionResource(versionByBuildUri("x", 100));
123
124 assertThat(tester.client.products().getVersion("x", ProductVersionSpecifier.buildNumber(100)),
125 contains(PRODUCT_VER_REP));
126 }
127
128 @Test
129 public void getVersionByBuildUsesVersionByNameResource() throws Exception
130 {
131 setupProductVersionResource(versionByNameUri("x", "1.0"));
132
133 assertThat(tester.client.products().getVersion("x", ProductVersionSpecifier.name("1.0")),
134 contains(PRODUCT_VER_REP));
135 }
136
137 @Test
138 public void findUsesProductsResource() throws Exception
139 {
140 setupProductsResource(productsApi());
141
142 assertThat(tester.client.products().find(ProductQuery.builder().build()), contains(PRODUCT_REP));
143 }
144
145 @Test
146 public void findReturnsPageWithCorrectSize() throws Exception
147 {
148 setupProductsResource(productsApi());
149
150 assertThat(tester.client.products().find(ProductQuery.builder().build()).size(), equalTo(1));
151 }
152
153 @Test
154 public void findReturnsPageWithCorrectTotalSize() throws Exception
155 {
156 setupProductsResource(productsApi());
157
158 assertThat(tester.client.products().find(ProductQuery.builder().build()).totalSize(), equalTo(2));
159 }
160
161 @Test
162 public void findReturnsPageWithReference() throws Exception
163 {
164 QueryBounds b = QueryBounds.limit(some(5));
165 UriBuilder uri = productsApi().queryParam("limit", 5);
166 setupProductsResource(uri, PRODUCTS_REP);
167
168 assertThat(tester.client.products().find(ProductQuery.builder().bounds(b).build()).getReference(),
169 equalTo(some(new PageReference<Product>(uri.build(), b, PageReader.<Product>stub()))));
170 }
171
172 @Test
173 public void findReturnsPageWithNoNextReferenceIfNoNextLink() throws Exception
174 {
175 setupProductsResource(productsApi(), PRODUCTS_REP_WITH_PREV);
176
177 assertThat(tester.client.products().find(ProductQuery.builder().build()).getNext(),
178 equalTo(Option.<PageReference<Product>>none()));
179 }
180
181 @Test
182 public void findReturnsPageWithNextReferenceIfNextLink() throws Exception
183 {
184 QueryBounds b = QueryBounds.limit(some(5));
185 UriBuilder uri = productsApi().queryParam("limit", 5);
186 setupProductsResource(uri, PRODUCTS_REP_WITH_NEXT);
187
188 assertThat(tester.client.products().find(ProductQuery.builder().bounds(b).build()).getNext(),
189 equalTo(some(new PageReference<Product>(LINK_NEXT_URI, b.withOffset(5), PageReader.<Product>stub()))));
190 }
191
192 @Test
193 public void findReturnsPageWithNextReferenceUsingSizeAsLimitIfLimitOmitted() throws Exception
194 {
195 setupProductsResource(productsApi(), PRODUCTS_REP_WITH_NEXT);
196
197 assertThat(tester.client.products().find(ProductQuery.builder().build()).getNext(),
198 equalTo(some(new PageReference<Product>(LINK_NEXT_URI,
199 QueryBounds.offset(1).withLimit(some(1)), PageReader.<Product>stub()))));
200 }
201
202 @Test
203 public void findReturnsPageWithNoPrevReferenceIfNoPrevLink() throws Exception
204 {
205 setupProductsResource(productsApi(), PRODUCTS_REP_WITH_NEXT);
206
207 assertThat(tester.client.products().find(ProductQuery.builder().build()).getPrevious(),
208 equalTo(Option.<PageReference<Product>>none()));
209 }
210
211 @Test
212 public void findReturnsPageWithPrevReferenceIfPrevLink() throws Exception
213 {
214 QueryBounds b = QueryBounds.offset(8).withLimit(some(5));
215 UriBuilder uri = productsApi().queryParam("offset", 8).queryParam("limit", 5);
216 setupProductsResource(uri, PRODUCTS_REP_WITH_PREV);
217
218 assertThat(tester.client.products().find(ProductQuery.builder().bounds(b).build()).getPrevious(),
219 equalTo(some(new PageReference<Product>(LINK_PREV_URI, b.withOffset(3), PageReader.<Product>stub()))));
220 }
221
222 @Test
223 public void findPassesOffsetInQueryString() throws Exception
224 {
225 QueryBounds b = QueryBounds.offset(5);
226 setupProductsResource(productsApi().queryParam("offset", "5"));
227
228 assertThat(tester.client.products().find(ProductQuery.builder().bounds(b).build()), contains(PRODUCT_REP));
229 }
230
231 @Test
232 public void findPassesLimitInQueryString() throws Exception
233 {
234 QueryBounds b = QueryBounds.limit(some(10));
235 setupProductsResource(productsApi().queryParam("limit", "10"));
236
237 assertThat(tester.client.products().find(ProductQuery.builder().bounds(b).build()), contains(PRODUCT_REP));
238 }
239
240 @Test
241 public void findPassesAppKeyInQueryString() throws Exception
242 {
243 setupProductsResource(productsApi().queryParam("application", "jira"));
244
245 assertThat(tester.client.products().find(ProductQuery.builder().application(some(JIRA)).build()), contains(PRODUCT_REP));
246 }
247
248 @Test
249 public void findPassesAppBuildNumberInQueryString() throws Exception
250 {
251 setupProductsResource(productsApi().queryParam("application", "jira").queryParam("applicationBuild", "123"));
252
253 assertThat(tester.client.products().find(ProductQuery.builder().application(some(JIRA)).appBuildNumber(some(123)).build()),
254 contains(PRODUCT_REP));
255 }
256
257 @Test
258 public void findPassesCostInQueryString() throws Exception
259 {
260 setupProductsResource(productsApi().queryParam("cost", "paid"));
261
262 assertThat(tester.client.products().find(ProductQuery.builder().cost(some(Cost.ALL_PAID)).build()),
263 contains(PRODUCT_REP));
264 }
265
266 @Test
267 public void findPassesVersionFlagInQueryString() throws Exception
268 {
269 setupProductsResource(productsApi().queryParam("withVersion", "true"));
270
271 assertThat(tester.client.products().find(ProductQuery.builder().withVersion(true).build()),
272 contains(PRODUCT_REP));
273 }
274
275 @Test
276 public void findPassesHostingInQueryString() throws Exception
277 {
278 setupProductsResource(productsApi().queryParam("hosting", "cloud"));
279
280 assertThat(tester.client.products().find(ProductQuery.builder().hosting(some(HostingType.CLOUD)).build()),
281 contains(PRODUCT_REP));
282 }
283
284 private UriBuilder productsApi()
285 {
286 return UriBuilder.fromUri(HOST_BASE + FAKE_PRODUCTS_PATH);
287 }
288
289 private UriBuilder productsApiZeroLengthQuery()
290 {
291 return UriBuilder.fromUri(HOST_BASE + FAKE_PRODUCTS_PATH).queryParam("limit", 0);
292 }
293
294 private UriBuilder productByKeyUri(String key)
295 {
296 return UriBuilder.fromUri(HOST_BASE + FAKE_PRODUCT_BY_KEY_PATH + key);
297 }
298
299 private UriBuilder latestVersionUri(String key)
300 {
301 return UriBuilder.fromUri(HOST_BASE + FAKE_PRODUCT_BY_KEY_PATH + key + "/latest");
302 }
303
304 private UriBuilder versionByBuildUri(String key, int build)
305 {
306 return UriBuilder.fromUri(HOST_BASE + FAKE_PRODUCT_BY_KEY_PATH + key + "/build/" + build);
307 }
308
309 private UriBuilder versionByNameUri(String key, String name)
310 {
311 return UriBuilder.fromUri(HOST_BASE + FAKE_PRODUCT_BY_KEY_PATH + key + "/name/" + name);
312 }
313
314 private void setupProductsResource(UriBuilder productsUri) throws Exception
315 {
316 setupProductsResource(productsUri, PRODUCTS_REP);
317 }
318
319 private void setupProductsResource(UriBuilder productsUri, InternalModel.Products rep) throws Exception
320 {
321 tester.mockResource(productsUri.build(), rep);
322 }
323
324 private void setupProductByKeyResource(UriBuilder uri) throws Exception
325 {
326 setupProductsResource(productsApiZeroLengthQuery());
327 tester.mockResource(uri.build(), PRODUCT_REP);
328 }
329
330 private void setupProductVersionResource(UriBuilder uri) throws Exception
331 {
332 setupProductsResource(productsApiZeroLengthQuery());
333 tester.mockResource(uri.build(), PRODUCT_VER_REP);
334 }
335 }