Skip to content

Commit 4cd51fa

Browse files
committed
Merge branch 'release/2.0.0-RC1'
2 parents fb9f858 + d24b915 commit 4cd51fa

File tree

70 files changed

+2671
-261
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+2671
-261
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Change Log
22

3+
## 2.0.0
4+
5+
- adds streaming
6+
- adds Room for caching Events
7+
8+
## 1.2.0
9+
10+
### Added
11+
12+
- adds search, uses new media.ccc.de API for search
13+
14+
### Fixed
15+
16+
- Fixes Bug with initially wrong used Aspect Ratios
17+
318
## 1.1.0
419

520
### Added

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ An Android TV App for the media API of the Chaos Computer Club e.V. (CCC) writte
88

99
* https://media.ccc.de
1010

11-
This App uses [a fork][c3media-base-fork] of [c3media-base][c3media-base-orig] by [Tobias Preuss][tobias-preuss].
11+
This App uses [c3media-base][c3media-base-orig] by [Tobias Preuss][tobias-preuss].
12+
In case Gradle can not find this dependency, check out the sources and deploy them locally.
1213

1314
The Logo ["Voctocat"][voctocat] is kindly provided by [Blinry][blinry] under CC BY-NC-SA 4.0 License.
1415

@@ -48,7 +49,6 @@ If you want to build a `release` version, it is important to replace the placeho
4849
limitations under the License.
4950

5051
[c3media-base-orig]: https://github.com/johnjohndoe/c3media-base
51-
[c3media-base-fork]: https://github.com/stefanmedack/c3media-base
5252
[tobias-preuss]: https://github.com/johnjohndoe
5353
[blinry]: https://github.com/blinry
5454
[stefan]: https://twitter.com/Zonic03

app/build.gradle

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,43 @@ apply plugin: 'io.fabric'
99
apply plugin: 'com.google.gms.oss.licenses.plugin'
1010

1111
ext {
12-
archComponentsVersion = "1.0.0-alpha9"
12+
archComponentsVersion = "1.0.0"
1313
assertjVersion = "3.8.0"
14+
c3mediaVersion = "2.0.0-SNAPSHOT"
1415
crashlyticsVersion = "2.6.8"
1516
daggerVersion = "2.11"
16-
exoplayerVersion = "r2.5.1"
17+
exoplayerVersion = "r2.5.3"
1718
glideVersion = "3.8.0"
18-
junitVersion = "4.12"
19+
gsonVersion = "2.8.2"
1920
paperParcelVersion = "2.0.4"
20-
playServicesVersion = "11.2.2"
21+
playServicesVersion = "11.4.0"
2122
rxAndroidVersion = "2.0.1"
22-
rxJavaVersion = "2.1.3"
23+
rxBindingVersion = "2.0.0"
24+
rxJavaVersion = "2.1.4"
2325
rxKotlinVersion = "2.1.0"
24-
supportLibVersion = "26.0.2"
26+
supportLibVersion = "26.1.0"
2527
timberVersion = "4.5.1"
28+
29+
// Test dependencies
30+
kluentVersion = "1.29"
31+
junitVersion = "4.12"
32+
runnerVersion = '1.0.1'
33+
rulesVersion = '1.0.1'
2634
}
2735

2836
android {
2937

3038
compileSdkVersion 26
31-
buildToolsVersion "26.0.1"
39+
buildToolsVersion '26.0.2'
3240
defaultConfig {
3341
applicationId "de.stefanmedack.ccctv"
3442
minSdkVersion 21
3543
targetSdkVersion 26
36-
versionCode 2
37-
versionName "1.1.0"
44+
versionCode 4
45+
versionName "2.0.0-RC1"
3846
resConfigs "en", "de"
3947
multiDexEnabled true
48+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
4049
}
4150

4251
signingConfigs {
@@ -65,6 +74,26 @@ android {
6574
signingConfig signingConfigs.release
6675
}
6776
}
77+
78+
// TODO think about reworking the dimensions/configs for streaming
79+
flavorDimensions "default"
80+
productFlavors {
81+
dev {
82+
buildConfigField "String", "STREAMING_API_BASE_URL", "\"http://gist.githubusercontent.com\""
83+
buildConfigField "String", "STREAMING_API_OFFERS_PATH",
84+
"\"/MaZderMind/a91f242efb2f446a2237d4596896efd6/raw/7ab4e206f19ed4d63a67917fe6e3a15a96218ac9/streams-v2.json\""
85+
// "\"/johnjohndoe/617bbfa2ac36f5148a049548b419e299/raw/7ab4e206f19ed4d63a67917fe6e3a15a96218ac9/streams-v2.json\""
86+
}
87+
live {
88+
buildConfigField "String", "STREAMING_API_BASE_URL", "\"http://streaming.media.ccc.de\""
89+
buildConfigField "String", "STREAMING_API_OFFERS_PATH", "\"/streams/v2.json\""
90+
}
91+
}
92+
93+
sourceSets {
94+
androidTest.java.srcDirs += "src/test-common/java"
95+
test.java.srcDirs += "src/test-common/java"
96+
}
6897
}
6998

7099
dependencies {
@@ -75,20 +104,27 @@ dependencies {
75104
implementation "com.android.support:appcompat-v7:$supportLibVersion"
76105
implementation "com.android.support:leanback-v17:$supportLibVersion"
77106

78-
// Architecture Components
107+
// Architecture Components - View Model (+ Lifecycles, LiveData)
79108
implementation "android.arch.lifecycle:runtime:$archComponentsVersion"
80109
implementation "android.arch.lifecycle:extensions:$archComponentsVersion"
81110
kapt "android.arch.lifecycle:compiler:$archComponentsVersion"
82111

112+
// Architecture Components - Room
113+
implementation "android.arch.persistence.room:runtime:$archComponentsVersion"
114+
implementation "android.arch.persistence.room:rxjava2:$archComponentsVersion"
115+
kapt "android.arch.persistence.room:compiler:$archComponentsVersion"
116+
83117
//Dagger 2 dependencies
84118
implementation "com.google.dagger:dagger:$daggerVersion"
85-
compile "com.google.dagger:dagger-android:$daggerVersion"
86-
compile "com.google.dagger:dagger-android-support:$daggerVersion"
119+
implementation "com.google.dagger:dagger-android:$daggerVersion"
120+
implementation "com.google.dagger:dagger-android-support:$daggerVersion"
87121
kapt "com.google.dagger:dagger-android-processor:$daggerVersion"
88122
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
89123

90-
// c3media API - TODO PR to Tobis Repo + replace by original release version
91-
implementation "com.github.stefanmedack:c3media-base:c9a508e640"
124+
// c3media library
125+
implementation "info.metadude.kotlin.library.c3media:c3media-rx-java-2:${c3mediaVersion}"
126+
// c3media streaming
127+
implementation "com.github.johnjohndoe:Brockman:1886e90a92029ceba978e3326202383c63ed8efd"
92128

93129
// Exo Player
94130
implementation "com.google.android.exoplayer:exoplayer:$exoplayerVersion"
@@ -101,11 +137,14 @@ dependencies {
101137
implementation "io.reactivex.rxjava2:rxkotlin:$rxKotlinVersion"
102138
implementation "io.reactivex.rxjava2:rxandroid:$rxAndroidVersion"
103139

140+
// RXBinding
141+
compile "com.jakewharton.rxbinding2:rxbinding-leanback-v17-kotlin:$rxBindingVersion"
142+
104143
// timber - better logging
105144
implementation "com.jakewharton.timber:timber:$timberVersion"
106145

107146
// Crashlytics
108-
compile("com.crashlytics.sdk.android:crashlytics:$crashlyticsVersion@aar") {
147+
implementation("com.crashlytics.sdk.android:crashlytics:$crashlyticsVersion@aar") {
109148
transitive = true
110149
}
111150

@@ -114,12 +153,22 @@ dependencies {
114153
implementation "nz.bradcampbell:paperparcel-kotlin:$paperParcelVersion" // Optional
115154
kapt "nz.bradcampbell:paperparcel-compiler:$paperParcelVersion"
116155

156+
// Gson
157+
implementation "com.google.code.gson:gson:$gsonVersion"
158+
117159
// Licenses Screen
118160
implementation "com.google.android.gms:play-services-oss-licenses:$playServicesVersion"
119161

120162
// Test dependencies
121-
testCompile "junit:junit:$junitVersion"
122-
testCompile "org.assertj:assertj-core:$assertjVersion"
163+
testImplementation "junit:junit:$junitVersion"
164+
testImplementation "org.amshove.kluent:kluent:$kluentVersion"
165+
166+
// Android Instrumented Test
167+
androidTestImplementation "com.android.support.test:runner:$runnerVersion"
168+
169+
// Arch Component
170+
androidTestImplementation "android.arch.core:core-testing:$archComponentsVersion"
171+
123172
}
124173

125174
static def getFormattedDate() {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package de.stefanmedack.ccctv.persistence
2+
3+
import android.arch.core.executor.testing.InstantTaskExecutorRule
4+
import android.arch.persistence.room.Room
5+
import android.support.test.InstrumentationRegistry
6+
import de.stefanmedack.ccctv.minimalConferenceEntity
7+
import org.junit.After
8+
import org.junit.Before
9+
import org.junit.Rule
10+
11+
abstract class BaseDbTest {
12+
13+
@get:Rule
14+
var instantTaskExecutorRule = InstantTaskExecutorRule()
15+
16+
protected lateinit var db: C3Db
17+
18+
@Before
19+
fun initDb() {
20+
db = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(), C3Db::class.java)
21+
.allowMainThreadQueries()
22+
.build()
23+
}
24+
25+
@After
26+
fun closeDb() {
27+
db.close()
28+
}
29+
30+
fun initDbWithConference(conferenceId : Int) {
31+
db.conferenceDao().insert(minimalConferenceEntity.copy(id = conferenceId))
32+
}
33+
34+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package de.stefanmedack.ccctv.persistence
2+
3+
import android.support.test.runner.AndroidJUnit4
4+
import de.stefanmedack.ccctv.fullConferenceEntity
5+
import de.stefanmedack.ccctv.minimalConferenceEntity
6+
import de.stefanmedack.ccctv.minimalEventEntity
7+
import de.stefanmedack.ccctv.persistence.entities.ConferenceWithEvents
8+
import de.stefanmedack.ccctv.persistence.entities.Event
9+
import org.junit.Assert
10+
import org.junit.Assert.assertEquals
11+
import org.junit.Test
12+
import org.junit.runner.RunWith
13+
14+
@RunWith(AndroidJUnit4::class)
15+
class ConferenceDaoTest : BaseDbTest() {
16+
17+
@Test
18+
fun get_conferences_from_empty_table_returns_empty_list() {
19+
db.conferenceDao().getConferences()
20+
.test()
21+
.assertValue(listOf())
22+
}
23+
24+
@Test
25+
fun insert_and_retrieve_minimal_conference() {
26+
db.conferenceDao().insert(minimalConferenceEntity)
27+
28+
val loadedConferences = db.conferenceDao().getConferenceById(minimalConferenceEntity.id).test()
29+
30+
loadedConferences.assertValue(minimalConferenceEntity)
31+
}
32+
33+
@Test
34+
fun insert_and_retrieve_full_conference() {
35+
db.conferenceDao().insert(fullConferenceEntity)
36+
37+
val loadedConferences = db.conferenceDao().getConferenceById(fullConferenceEntity.id).test()
38+
39+
loadedConferences.assertValue(fullConferenceEntity)
40+
}
41+
42+
@Test
43+
fun insert_and_retrieve_multiple_conferences() {
44+
val conferences = listOf(
45+
minimalConferenceEntity.copy(id = 1),
46+
fullConferenceEntity.copy(id = 2)
47+
)
48+
db.conferenceDao().insertAll(conferences)
49+
50+
val loadedConferences = db.conferenceDao().getConferences().test()
51+
52+
loadedConferences.assertValue(conferences)
53+
}
54+
55+
@Test
56+
fun insert_a_conference_with_same_id_should_override_old_conference() {
57+
val oldConference = minimalConferenceEntity
58+
db.conferenceDao().insert(oldConference)
59+
60+
val newConference = oldConference.copy(title = "new_title")
61+
db.conferenceDao().insert(newConference)
62+
63+
val loadedConferences = db.conferenceDao().getConferences().test().values()[0]
64+
65+
Assert.assertNotEquals(loadedConferences[0], oldConference)
66+
assertEquals(loadedConferences[0], newConference)
67+
}
68+
69+
// Conferences with Events
70+
71+
@Test
72+
fun get_conferences_with_events_from_empty_table_returns_empty_list() {
73+
db.conferenceDao().getConferencesWithEvents()
74+
.test()
75+
.assertValue(listOf())
76+
}
77+
78+
@Test
79+
fun insert_and_retrieve_single_conference_without_event() {
80+
db.conferenceDao().insert(minimalConferenceEntity)
81+
82+
val loadedConferences = db.conferenceDao().getConferencesWithEvents().test()
83+
84+
loadedConferences.assertValue(listOf(ConferenceWithEvents(minimalConferenceEntity, listOf())))
85+
}
86+
87+
@Test
88+
fun insert_and_retrieve_multiple_conferences_with_events() {
89+
val conferences = listOf(
90+
minimalConferenceEntity.copy(id = 1),
91+
fullConferenceEntity.copy(id = 2)
92+
)
93+
val eventForFirstConference = minimalEventEntity.copy(conferenceId = 1)
94+
95+
db.conferenceDao().insertAll(conferences)
96+
db.eventDao().insert(eventForFirstConference)
97+
98+
val loadedConferences = db.conferenceDao().getConferencesWithEvents().test().values()[0]
99+
100+
assertEquals(loadedConferences[0].conference, conferences[0])
101+
assertEquals(loadedConferences[0].events, listOf(eventForFirstConference))
102+
assertEquals(loadedConferences[1].conference, conferences[1])
103+
assertEquals(loadedConferences[1].events, listOf<Event>())
104+
}
105+
106+
@Test
107+
fun insert_and_retrieve_multiple_conferences_with_events_in_single_insert() {
108+
val conferences = listOf(
109+
minimalConferenceEntity.copy(id = 1),
110+
minimalConferenceEntity.copy(id = 2)
111+
)
112+
val eventForConf1 = minimalEventEntity.copy(conferenceId = 1)
113+
val conferencesWithEvents = conferences.mapIndexed { index, conf ->
114+
ConferenceWithEvents(
115+
conf,
116+
if (index == 0) listOf(eventForConf1) else listOf()
117+
)
118+
}
119+
120+
db.conferenceDao().insertConferencesWithEvents(conferences, listOf(eventForConf1))
121+
122+
val loadedConferences = db.conferenceDao().getConferencesWithEvents().test()
123+
124+
loadedConferences.assertValue(conferencesWithEvents)
125+
}
126+
127+
@Test
128+
fun insert_and_retrieve_multiple_conferences_with_events_filtered_by_group() {
129+
val conferences = listOf(
130+
minimalConferenceEntity.copy(id = 1, slug = "congress/33c3"),
131+
fullConferenceEntity.copy(id = 2, slug = "not_congress/droidcon")
132+
)
133+
134+
db.conferenceDao().insertAll(conferences)
135+
val loadedConferences = db.conferenceDao().getConferencesWithEvents("congress").test().values()[0]
136+
137+
assertEquals(loadedConferences.size, 1)
138+
assertEquals(loadedConferences[0].conference, conferences[0])
139+
}
140+
}

0 commit comments

Comments
 (0)