Skip to content

Commit 313d6f0

Browse files
Fix findMaxAppVersionCode ignores inactive bundles/apks
- findMaxAppVersionCode no longer ignores inactive bundles/apks - instead of extracting the highest versionCode from all tracks, it now extracts the highest versionCode of all bundles and APKs Resolves #1197
1 parent c53a82f commit 313d6f0

6 files changed

Lines changed: 168 additions & 73 deletions

File tree

play/android-publisher/src/main/kotlin/com/github/triplet/gradle/androidpublisher/internal/DefaultEditManager.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,7 @@ internal class DefaultEditManager(
4848
}
4949

5050
override fun findMaxAppVersionCode(): Long {
51-
return tracks.findHighestTrack()?.releases.orEmpty()
52-
.flatMap { it.versionCodes.orEmpty() }
53-
.maxOrNull() ?: 1
51+
return publisher.findMaxAppVersionCode(editId).toLong()
5452
}
5553

5654
override fun findLeastStableTrackName(): String? {

play/android-publisher/src/main/kotlin/com/github/triplet/gradle/androidpublisher/internal/DefaultPlayPublisher.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,18 @@ internal class DefaultPlayPublisher(
106106
}
107107
}
108108

109+
override fun findMaxAppVersionCode(editId: String): Int {
110+
val maxBundle = publisher.edits().bundles().list(appId, editId).execute()
111+
?.bundles.orEmpty()
112+
.maxOfOrNull { it.versionCode ?: 0 } ?: 0
113+
114+
val maxApk = publisher.edits().apks().list(appId, editId).execute()
115+
?.apks.orEmpty()
116+
.maxOfOrNull { it.versionCode ?: 0 } ?: 0
117+
118+
return maxOf(maxBundle, maxApk).takeIf { it > 0 } ?: 1
119+
}
120+
109121
override fun listTracks(editId: String): List<Track> {
110122
return publisher.edits().tracks().list(appId, editId).execute()?.tracks.orEmpty()
111123
}

play/android-publisher/src/main/kotlin/com/github/triplet/gradle/androidpublisher/internal/InternalPlayPublisher.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ internal interface InternalPlayPublisher : PlayPublisher {
3434

3535
fun updateTrack(editId: String, track: Track)
3636

37+
fun findMaxAppVersionCode(editId: String): Int
38+
3739
@Throws(IOException::class)
3840
fun uploadBundle(editId: String, bundleFile: File): Bundle
3941

play/android-publisher/src/test/kotlin/com/github/triplet/gradle/androidpublisher/internal/DefaultEditManagerTest.kt

Lines changed: 13 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import com.google.api.services.androidpublisher.model.Image
1313
import com.google.api.services.androidpublisher.model.Listing
1414
import com.google.api.services.androidpublisher.model.LocalizedText
1515
import com.google.api.services.androidpublisher.model.Track
16-
import com.google.api.services.androidpublisher.model.TrackRelease
1716
import com.google.common.truth.Truth.assertThat
1817
import org.junit.jupiter.api.Test
1918
import org.junit.jupiter.api.assertThrows
@@ -29,7 +28,8 @@ import java.io.File
2928
class DefaultEditManagerTest {
3029
private var mockPublisher = mock(InternalPlayPublisher::class.java)
3130
private var mockTracks = mock(TrackManager::class.java)
32-
private var edits: EditManager = DefaultEditManager(mockPublisher, mockTracks, "edit-id")
31+
private val editId = "edit-id"
32+
private var edits: EditManager = DefaultEditManager(mockPublisher, mockTracks, editId)
3333

3434
private var mockFile = mock(File::class.java)
3535

@@ -149,7 +149,7 @@ class DefaultEditManagerTest {
149149
)
150150

151151
verify(mockPublisher)
152-
.uploadDeobfuscationFile(eq("edit-id"), eq(mockFile), eq(888), eq("proguard"))
152+
.uploadDeobfuscationFile(eq(editId), eq(mockFile), eq(888), eq("proguard"))
153153
}
154154

155155
@Test
@@ -169,7 +169,7 @@ class DefaultEditManagerTest {
169169
)
170170

171171
verify(mockPublisher)
172-
.uploadDeobfuscationFile(eq("edit-id"), eq(mockFile), eq(888), eq("nativeCode"))
172+
.uploadDeobfuscationFile(eq(editId), eq(mockFile), eq(888), eq("nativeCode"))
173173
}
174174

175175
@Test
@@ -223,8 +223,8 @@ class DefaultEditManagerTest {
223223
patchObbRetainable = 321
224224
)
225225

226-
verify(mockPublisher).attachObb(eq("edit-id"), eq("main"), eq(888), eq(123))
227-
verify(mockPublisher).attachObb(eq("edit-id"), eq("patch"), eq(888), eq(321))
226+
verify(mockPublisher).attachObb(eq(editId), eq("main"), eq(888), eq(123))
227+
verify(mockPublisher).attachObb(eq(editId), eq("patch"), eq(888), eq(321))
228228
}
229229

230230
@Test
@@ -324,70 +324,14 @@ class DefaultEditManagerTest {
324324
}
325325

326326
@Test
327-
fun `findMaxAppVersionCode returns 1 on empty tracks`() {
328-
`when`(mockTracks.findHighestTrack()).thenReturn(null)
329-
330-
val max = edits.findMaxAppVersionCode()
331-
332-
assertThat(max).isEqualTo(1)
333-
}
334-
335-
@Test
336-
fun `findMaxAppVersionCode returns 1 on null releases`() {
337-
`when`(mockTracks.findHighestTrack()).thenReturn(Track())
338-
339-
val max = edits.findMaxAppVersionCode()
340-
341-
assertThat(max).isEqualTo(1)
342-
}
343-
344-
@Test
345-
fun `findMaxAppVersionCode succeeds with single track, single release, singe version code`() {
346-
`when`(mockTracks.findHighestTrack()).thenReturn(Track().apply {
347-
releases = listOf(
348-
TrackRelease().apply {
349-
versionCodes = listOf(5)
350-
}
351-
)
352-
})
327+
fun `findMaxAppVersionCode delegates to publisher`() {
328+
`when`(mockPublisher.findMaxAppVersionCode(editId)).thenReturn(91)
353329

354330
val max = edits.findMaxAppVersionCode()
355331

356-
assertThat(max).isEqualTo(5)
332+
assertThat(max).isEqualTo(91)
357333
}
358334

359-
@Test
360-
fun `findMaxAppVersionCode succeeds with single track, single release, multi version code`() {
361-
`when`(mockTracks.findHighestTrack()).thenReturn(Track().apply {
362-
releases = listOf(
363-
TrackRelease().apply {
364-
versionCodes = listOf(5, 4, 8, 7)
365-
}
366-
)
367-
})
368-
369-
val max = edits.findMaxAppVersionCode()
370-
371-
assertThat(max).isEqualTo(8)
372-
}
373-
374-
@Test
375-
fun `findMaxAppVersionCode succeeds with single track, multi release, multi version code`() {
376-
`when`(mockTracks.findHighestTrack()).thenReturn(Track().apply {
377-
releases = listOf(
378-
TrackRelease().apply {
379-
versionCodes = listOf(5, 4, 8, 7)
380-
},
381-
TrackRelease().apply {
382-
versionCodes = listOf(85, 7, 36, 5)
383-
}
384-
)
385-
})
386-
387-
val max = edits.findMaxAppVersionCode()
388-
389-
assertThat(max).isEqualTo(85)
390-
}
391335

392336
@Test
393337
fun `findLeastStableTrackName returns null on null track`() {
@@ -453,7 +397,7 @@ class DefaultEditManagerTest {
453397
fun `publishAppDetails forwards data to publisher`() {
454398
edits.publishAppDetails("lang", "email", "phone", "website")
455399

456-
verify(mockPublisher).updateDetails(eq("edit-id"), eq(AppDetails().apply {
400+
verify(mockPublisher).updateDetails(eq(editId), eq(AppDetails().apply {
457401
defaultLanguage = "lang"
458402
contactEmail = "email"
459403
contactPhone = "phone"
@@ -465,7 +409,7 @@ class DefaultEditManagerTest {
465409
fun `publishListing forwards data to publisher`() {
466410
edits.publishListing("lang", "title", "short", "full", "url")
467411

468-
verify(mockPublisher).updateListing(eq("edit-id"), eq("lang"), eq(Listing().apply {
412+
verify(mockPublisher).updateListing(eq(editId), eq("lang"), eq(Listing().apply {
469413
title = "title"
470414
shortDescription = "short"
471415
fullDescription = "full"
@@ -477,8 +421,8 @@ class DefaultEditManagerTest {
477421
fun `publishImages forwards data to publisher`() {
478422
edits.publishImages("lang", "phoneScreenshots", listOf(mockFile))
479423

480-
verify(mockPublisher).deleteImages(eq("edit-id"), eq("lang"), eq("phoneScreenshots"))
424+
verify(mockPublisher).deleteImages(eq(editId), eq("lang"), eq("phoneScreenshots"))
481425
verify(mockPublisher).uploadImage(
482-
eq("edit-id"), eq("lang"), eq("phoneScreenshots"), eq(mockFile))
426+
eq(editId), eq("lang"), eq("phoneScreenshots"), eq(mockFile))
483427
}
484428
}
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
package com.github.triplet.gradle.androidpublisher.internal
2+
3+
import com.google.api.services.androidpublisher.AndroidPublisher
4+
import com.google.api.services.androidpublisher.model.Apk
5+
import com.google.api.services.androidpublisher.model.ApksListResponse
6+
import com.google.api.services.androidpublisher.model.Bundle
7+
import com.google.api.services.androidpublisher.model.BundlesListResponse
8+
import com.google.common.truth.Truth.assertThat
9+
import org.junit.jupiter.api.BeforeEach
10+
import org.junit.jupiter.api.Test
11+
import org.mockito.Mockito.mock
12+
import org.mockito.Mockito.`when`
13+
14+
class DefaultPlayPublisherTest {
15+
private val mockAndroidPublisher = mock(AndroidPublisher::class.java)
16+
private val appId = "appId"
17+
private val editId = "editId"
18+
19+
private val mockEdits = mock(AndroidPublisher.Edits::class.java)
20+
21+
private val mockBundles = mock(AndroidPublisher.Edits.Bundles::class.java)
22+
private val mockBundlesList = mock(AndroidPublisher.Edits.Bundles.List::class.java)
23+
private val mockBundlesResponse = mock(BundlesListResponse::class.java)
24+
25+
private val mockApks = mock(AndroidPublisher.Edits.Apks::class.java)
26+
private val mockApksList = mock(AndroidPublisher.Edits.Apks.List::class.java)
27+
private val mockApksResponse = mock(ApksListResponse::class.java)
28+
29+
private val publisher = DefaultPlayPublisher(mockAndroidPublisher, appId)
30+
31+
@BeforeEach
32+
fun setUp() {
33+
`when`(mockAndroidPublisher.edits()).thenReturn(mockEdits)
34+
35+
`when`(mockEdits.bundles()).thenReturn(mockBundles)
36+
`when`(mockBundles.list(appId, editId)).thenReturn(mockBundlesList)
37+
`when`(mockBundlesList.execute()).thenReturn(mockBundlesResponse)
38+
39+
`when`(mockEdits.apks()).thenReturn(mockApks)
40+
`when`(mockApks.list(appId, editId)).thenReturn(mockApksList)
41+
`when`(mockApksList.execute()).thenReturn(mockApksResponse)
42+
}
43+
44+
@Test
45+
fun `findMaxAppVersionCode returns 1 on null bundles and null apks`() {
46+
`when`(mockBundlesResponse.bundles).thenReturn(null)
47+
`when`(mockApksResponse.apks).thenReturn(null)
48+
49+
val max = publisher.findMaxAppVersionCode(editId)
50+
51+
assertThat(max).isEqualTo(1)
52+
}
53+
54+
@Test
55+
fun `findMaxAppVersionCode returns 1 on empty bundles and empty apks`() {
56+
`when`(mockBundlesResponse.bundles).thenReturn(emptyList())
57+
`when`(mockApksResponse.apks).thenReturn(emptyList())
58+
59+
val max = publisher.findMaxAppVersionCode(editId)
60+
61+
assertThat(max).isEqualTo(1)
62+
}
63+
64+
private fun bundle(versionCode: Int): Bundle {
65+
val bundle = Bundle()
66+
bundle.versionCode = versionCode
67+
return bundle
68+
}
69+
70+
private fun apk(versionCode: Int): Apk {
71+
val apk = Apk()
72+
apk.versionCode = versionCode
73+
return apk
74+
}
75+
76+
@Test
77+
fun `findMaxAppVersionCode succeeds with single bundle, no apks`() {
78+
`when`(mockBundlesResponse.bundles).thenReturn(listOf(bundle(5)))
79+
`when`(mockApksResponse.apks).thenReturn(emptyList())
80+
81+
val max = publisher.findMaxAppVersionCode(editId)
82+
83+
assertThat(max).isEqualTo(5)
84+
}
85+
86+
@Test
87+
fun `findMaxAppVersionCode succeeds with no bundles, single apk`() {
88+
`when`(mockBundlesResponse.bundles).thenReturn(emptyList())
89+
`when`(mockApksResponse.apks).thenReturn(listOf(apk(6)))
90+
91+
val max = publisher.findMaxAppVersionCode(editId)
92+
93+
assertThat(max).isEqualTo(6)
94+
}
95+
96+
@Test
97+
fun `findMaxAppVersionCode succeeds with multiple bundles and apks, max in bundles`() {
98+
`when`(mockBundlesResponse.bundles).thenReturn(
99+
listOf(
100+
bundle(5),
101+
bundle(12),
102+
bundle(8),
103+
)
104+
)
105+
`when`(mockApksResponse.apks).thenReturn(
106+
listOf(
107+
apk(3),
108+
apk(7),
109+
apk(2),
110+
)
111+
)
112+
113+
val max = publisher.findMaxAppVersionCode(editId)
114+
115+
assertThat(max).isEqualTo(12)
116+
}
117+
118+
@Test
119+
fun `findMaxAppVersionCode succeeds with multiple bundles and apks, max in apks`() {
120+
`when`(mockBundlesResponse.bundles).thenReturn(
121+
listOf(
122+
bundle(5),
123+
bundle(2),
124+
bundle(8),
125+
)
126+
)
127+
`when`(mockApksResponse.apks).thenReturn(
128+
listOf(
129+
apk(3),
130+
apk(15),
131+
apk(12),
132+
)
133+
)
134+
135+
val max = publisher.findMaxAppVersionCode(editId)
136+
137+
assertThat(max).isEqualTo(15)
138+
}
139+
}

version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
5.0.0-SNAPSHOT
1+
5.0.1-SNAPSHOT

0 commit comments

Comments
 (0)