Skip to content

Commit 968e7af

Browse files
committed
feat: support relevant dates object
The changes adds support for the relevant dates object as per documentation on: https://developer.apple.com/documentation/walletpasses/pass/relevantdates-data.dictionary
1 parent 65ff331 commit 968e7af

File tree

7 files changed

+368
-41
lines changed

7 files changed

+368
-41
lines changed

jpasskit/src/main/java/de/brendamour/jpasskit/PKPass.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ public class PKPass implements Cloneable, Serializable {
5656

5757
protected List<PKBeacon> beacons;
5858
protected List<PKLocation> locations;
59+
protected PKRelevantDates relevantDates;
5960

6061
protected List<PKBarcode> barcodes;
6162

@@ -164,6 +165,10 @@ public List<PKLocation> getLocations() {
164165
return locations;
165166
}
166167

168+
public PKRelevantDates getRelevantDates() {
169+
return relevantDates;
170+
}
171+
167172
public List<PKBarcode> getBarcodes() {
168173
return barcodes;
169174
}

jpasskit/src/main/java/de/brendamour/jpasskit/PKPassBuilder.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ public PKPassBuilder of(final PKPass pass) {
115115
}
116116
this.beacons = BuilderUtils.toBeaconBuilderList(pass.getBeacons());
117117
this.locations = BuilderUtils.toLocationBuilderList(pass.getLocations());
118+
if (pass.relevantDates != null) {
119+
this.pkPass.relevantDates = pass.relevantDates.clone();
120+
}
118121
this.barcodes = BuilderUtils.toBarcodeBuilderList(pass.getBarcodes());
119122
this.associatedApps = BuilderUtils.toAssociatedAppBuilderList(pass.getAssociatedApps());
120123
if (pass.getAssociatedStoreIdentifiers() != null) {
@@ -239,6 +242,15 @@ public PKPassBuilder locations(List<PKLocation> locations) {
239242
return this;
240243
}
241244

245+
public PKPassBuilder relevantDates(PKRelevantDates relevantDates) {
246+
this.pkPass.relevantDates = relevantDates;
247+
return this;
248+
}
249+
250+
public PKPassBuilder relevantDatesBuilder(PKRelevantDatesBuilder relevantDatesBuilder) {
251+
return relevantDates(relevantDatesBuilder.build());
252+
}
253+
242254
public PKPassBuilder barcodeBuilder(PKBarcodeBuilder barcode) {
243255
if (barcode != null) {
244256
this.barcodes.add(barcode);
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package de.brendamour.jpasskit;
2+
3+
import org.apache.commons.lang3.builder.ToStringBuilder;
4+
5+
import java.io.Serializable;
6+
import java.time.Instant;
7+
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
10+
@JsonDeserialize(builder = PKRelevantDatesBuilder.class)
11+
public class PKRelevantDates implements Cloneable, Serializable {
12+
13+
private static final long serialVersionUID = -8742901234567890123L;
14+
15+
protected Instant date;
16+
protected Instant endDate;
17+
protected Instant startDate;
18+
19+
protected PKRelevantDates() {
20+
}
21+
22+
/**
23+
* The date and time when the pass becomes relevant.
24+
* Wallet automatically calculates a relevancy interval from this date.
25+
*
26+
* @return date as Instant
27+
*/
28+
public Instant getDate() {
29+
return date;
30+
}
31+
32+
/**
33+
* The date and time for the pass relevancy interval to end.
34+
* Required when providing startDate.
35+
*
36+
* @return end date as Instant
37+
*/
38+
public Instant getEndDate() {
39+
return endDate;
40+
}
41+
42+
/**
43+
* The date and time for the pass relevancy interval to begin.
44+
*
45+
* @return start date as Instant
46+
*/
47+
public Instant getStartDate() {
48+
return startDate;
49+
}
50+
51+
@Override
52+
protected PKRelevantDates clone() {
53+
try {
54+
return (PKRelevantDates) super.clone();
55+
} catch (CloneNotSupportedException ex) {
56+
throw new IllegalStateException("Failed to clone PKRelevantDates instance", ex);
57+
}
58+
}
59+
60+
@Override
61+
public String toString() {
62+
return ToStringBuilder.reflectionToString(this);
63+
}
64+
65+
public static PKRelevantDatesBuilder builder() {
66+
return new PKRelevantDatesBuilder();
67+
}
68+
69+
public static PKRelevantDatesBuilder builder(PKRelevantDates relevantDates) {
70+
return builder().of(relevantDates);
71+
}
72+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package de.brendamour.jpasskit;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
5+
6+
import java.time.Instant;
7+
8+
/**
9+
* Allows constructing and validating {@link PKRelevantDates} entities.
10+
*/
11+
@JsonPOJOBuilder(withPrefix = "")
12+
public class PKRelevantDatesBuilder implements IPKBuilder<PKRelevantDates> {
13+
14+
private PKRelevantDates relevantDates;
15+
16+
protected PKRelevantDatesBuilder() {
17+
this.relevantDates = new PKRelevantDates();
18+
}
19+
20+
@Override
21+
public PKRelevantDatesBuilder of(final PKRelevantDates source) {
22+
if (source == null) {
23+
return this;
24+
}
25+
26+
this.relevantDates.date = source.date;
27+
this.relevantDates.endDate = source.endDate;
28+
this.relevantDates.startDate = source.startDate;
29+
30+
return this;
31+
}
32+
33+
/**
34+
* The date and time when the pass becomes relevant.
35+
* Wallet automatically calculates a relevancy interval from this date.
36+
*
37+
* @param date date as Instant
38+
* @return current builder instance for chaining
39+
*/
40+
@JsonProperty("date")
41+
public PKRelevantDatesBuilder date(Instant date) {
42+
this.relevantDates.date = date;
43+
return this;
44+
}
45+
46+
/**
47+
* The date and time for the pass relevancy interval to end.
48+
* Required when providing startDate.
49+
*
50+
* @param endDate end date as Instant
51+
* @return current builder instance for chaining
52+
*/
53+
@JsonProperty("endDate")
54+
public PKRelevantDatesBuilder endDate(Instant endDate) {
55+
this.relevantDates.endDate = endDate;
56+
return this;
57+
}
58+
59+
/**
60+
* The date and time for the pass relevancy interval to begin.
61+
*
62+
* @param startDate start date as Instant
63+
* @return current builder instance for chaining
64+
*/
65+
@JsonProperty("startDate")
66+
public PKRelevantDatesBuilder startDate(Instant startDate) {
67+
this.relevantDates.startDate = startDate;
68+
return this;
69+
}
70+
71+
@Override
72+
public PKRelevantDates build() {
73+
return this.relevantDates;
74+
}
75+
}

jpasskit/src/test/java/de/brendamour/jpasskit/PKPassTest.java

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/**
22
* Copyright (C) 2024 Patrice Brend'amour <[email protected]>
3-
*
3+
* <p>
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
1212
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -15,35 +15,28 @@
1515
*/
1616
package de.brendamour.jpasskit;
1717

18-
import static de.brendamour.jpasskit.passes.PKGenericPassTest.SOME;
19-
import static de.brendamour.jpasskit.passes.PKGenericPassTest.field;
20-
import java.time.Instant;
21-
import static org.assertj.core.api.Assertions.assertThat;
22-
import static org.mockito.Mockito.mock;
23-
import static org.mockito.Mockito.when;
18+
import com.google.common.collect.ImmutableMap;
19+
import de.brendamour.jpasskit.enums.PKBarcodeFormat;
20+
import de.brendamour.jpasskit.enums.PKTransitType;
21+
import de.brendamour.jpasskit.passes.*;
22+
import org.testng.Assert;
23+
import org.testng.annotations.BeforeMethod;
24+
import org.testng.annotations.Test;
2425

25-
import java.awt.Color;
26+
import java.awt.*;
2627
import java.net.MalformedURLException;
2728
import java.net.URL;
29+
import java.time.Instant;
2830
import java.util.ArrayList;
2931
import java.util.Arrays;
3032
import java.util.List;
3133
import java.util.Map;
3234

33-
import de.brendamour.jpasskit.enums.PKTransitType;
34-
import de.brendamour.jpasskit.passes.PKBoardingPass;
35-
import de.brendamour.jpasskit.passes.PKCoupon;
36-
import de.brendamour.jpasskit.passes.PKEventTicket;
37-
import de.brendamour.jpasskit.passes.PKGenericPass;
38-
import de.brendamour.jpasskit.passes.PKGenericPassBuilder;
39-
import de.brendamour.jpasskit.passes.PKStoreCard;
40-
import org.testng.Assert;
41-
import org.testng.annotations.BeforeMethod;
42-
import org.testng.annotations.Test;
43-
44-
import com.google.common.collect.ImmutableMap;
45-
46-
import de.brendamour.jpasskit.enums.PKBarcodeFormat;
35+
import static de.brendamour.jpasskit.passes.PKGenericPassTest.SOME;
36+
import static de.brendamour.jpasskit.passes.PKGenericPassTest.field;
37+
import static org.assertj.core.api.Assertions.assertThat;
38+
import static org.mockito.Mockito.mock;
39+
import static org.mockito.Mockito.when;
4740

4841
public class PKPassTest {
4942

@@ -67,6 +60,11 @@ public class PKPassTest {
6760
private static final Map<String, Object> USER_INFO = ImmutableMap.<String, Object> of("name", "John Doe");
6861
private static final Instant EXPIRATION_DATE = Instant.now();
6962
private static final long ASSOCIATED_STORE_IDENTIFIER = 1L;
63+
private static final PKRelevantDates RELEVANT_DATES = PKRelevantDates.builder()
64+
.date(Instant.now())
65+
.startDate(Instant.now().minusSeconds(3600))
66+
.endDate(Instant.now().plusSeconds(7200))
67+
.build();
7068

7169
private PKPassBuilder builder;
7270

@@ -145,6 +143,7 @@ public void test_gettersBasic() {
145143
assertThat(pass.getUserInfo()).isNull();
146144
assertThat(pass.getExpirationDate()).isNull();
147145
assertThat(pass.getBarcodes()).isNotNull().isEmpty();
146+
assertThat(pass.getRelevantDates()).isNull();
148147
}
149148

150149
@Test
@@ -180,6 +179,19 @@ public void test_getters() {
180179
assertThat(this.builder.isValid()).isFalse();
181180
}
182181

182+
@Test
183+
public void test_getRelevantDates() {
184+
assertThat(this.builder
185+
.relevantDates(RELEVANT_DATES)
186+
.build()
187+
.getRelevantDates()).isEqualTo(RELEVANT_DATES);
188+
189+
assertThat(this.builder
190+
.relevantDates((PKRelevantDates) null)
191+
.build()
192+
.getRelevantDates()).isNull();
193+
}
194+
183195
@Test
184196
public void test_getBackgroundColor() {
185197
assertThat(this.builder
@@ -275,8 +287,7 @@ public void test_getGeneric() {
275287

276288
PKPass clone = PKPass.builder(pass).build();
277289

278-
assertThat(clone)
279-
.isEqualToComparingFieldByFieldRecursively(pass);
290+
assertThat(clone).usingRecursiveComparison().isEqualTo(pass);
280291
}
281292

282293
@Test
@@ -293,8 +304,7 @@ public void test_getEventTicket() {
293304

294305
PKPass clone = PKPass.builder(pass).build();
295306

296-
assertThat(clone)
297-
.isEqualToComparingFieldByFieldRecursively(pass);
307+
assertThat(clone).usingRecursiveComparison().isEqualTo(pass);
298308
}
299309

300310
@Test
@@ -311,8 +321,7 @@ public void test_getCoupon() {
311321

312322
PKPass clone = PKPass.builder(pass).build();
313323

314-
assertThat(clone)
315-
.isEqualToComparingFieldByFieldRecursively(pass);
324+
assertThat(clone).usingRecursiveComparison().isEqualTo(pass);
316325
}
317326

318327
@Test
@@ -329,8 +338,7 @@ public void test_getStoreCard() {
329338

330339
PKPass clone = PKPass.builder(pass).build();
331340

332-
assertThat(clone)
333-
.isEqualToComparingFieldByFieldRecursively(pass);
341+
assertThat(clone).usingRecursiveComparison().isEqualTo(pass);
334342
}
335343

336344
@Test
@@ -347,8 +355,7 @@ public void test_getBoardingPass() {
347355

348356
PKPass clone = PKPass.builder(pass).build();
349357

350-
assertThat(clone)
351-
.isEqualToComparingFieldByFieldRecursively(pass);
358+
assertThat(clone).usingRecursiveComparison().isEqualTo(pass);
352359
}
353360

354361
private static URL asUrl(String value) {

0 commit comments

Comments
 (0)