Change-Id: I239cdc28237a87a0ed6599892e8ac7c61776a46dpull/2/head
parent
632bc62ed5
commit
c75f7ed025
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.fake
|
||||
|
||||
import com.google.samples.apps.nowinandroid.data.network.NetworkNewsResource
|
||||
import com.google.samples.apps.nowinandroid.data.network.NiANetwork
|
||||
import com.google.samples.apps.nowinandroid.di.NiaDispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.decodeFromString
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
/**
|
||||
* [NiANetwork] implementation that provides static news resources to aid development
|
||||
*/
|
||||
class FakeNiANetwork(
|
||||
private val dispatchers: NiaDispatchers,
|
||||
private val networkJson: Json
|
||||
) : NiANetwork {
|
||||
override suspend fun getNewsResources(): List<NetworkNewsResource> =
|
||||
withContext(dispatchers.IO) {
|
||||
networkJson.decodeFromString<ResourceData>(FakeDataSource.data).resources
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Representation of resources as fetched from [FakeDataSource]
|
||||
*/
|
||||
@Serializable
|
||||
private data class ResourceData(
|
||||
val resources: List<NetworkNewsResource>
|
||||
)
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.AuthorEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.EpisodeAuthorCrossRef
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.EpisodeEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceAuthorCrossRef
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceTopicCrossRef
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.TopicEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.utilities.InstantConverter
|
||||
import com.google.samples.apps.nowinandroid.data.local.utilities.NewsResourceTypeConverter
|
||||
|
||||
// TODO: ADD DAOs
|
||||
@Database(
|
||||
entities = [
|
||||
AuthorEntity::class,
|
||||
EpisodeAuthorCrossRef::class,
|
||||
EpisodeEntity::class,
|
||||
NewsResourceAuthorCrossRef::class,
|
||||
NewsResourceEntity::class,
|
||||
NewsResourceTopicCrossRef::class,
|
||||
TopicEntity::class,
|
||||
],
|
||||
version = 1,
|
||||
)
|
||||
@TypeConverters(
|
||||
InstantConverter::class,
|
||||
NewsResourceTypeConverter::class,
|
||||
)
|
||||
abstract class NiADatabase : RoomDatabase()
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
/**
|
||||
* Defines an author for either an [EpisodeEntity] or [NewsResourceEntity].
|
||||
* It has a many to many relationship with both entities
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "authors",
|
||||
indices = [
|
||||
Index(value = ["name"], unique = true)
|
||||
],
|
||||
)
|
||||
data class AuthorEntity(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
val name: String,
|
||||
@ColumnInfo(name = "image_url")
|
||||
val imageUrl: String,
|
||||
)
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
|
||||
/**
|
||||
* Cross reference for many to many relationship between [EpisodeEntity] and [AuthorEntity]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "episodes_authors",
|
||||
primaryKeys = ["episode_id", "author_id"],
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = EpisodeEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["episode_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = AuthorEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["author_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
]
|
||||
)
|
||||
data class EpisodeAuthorCrossRef(
|
||||
@ColumnInfo(name = "episode_id")
|
||||
val episodeId: Int,
|
||||
@ColumnInfo(name = "author_id")
|
||||
val authorId: Long,
|
||||
)
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
/**
|
||||
* Defines an NiA episode.
|
||||
* It is a parent in a 1 to many relationship with [NewsResourceEntity]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "episodes",
|
||||
)
|
||||
data class EpisodeEntity(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
val name: String,
|
||||
@ColumnInfo(name = "publish_date")
|
||||
val publishDate: Instant,
|
||||
@ColumnInfo(name = "alternate_video")
|
||||
val alternateVideo: String?,
|
||||
@ColumnInfo(name = "alternate_audio")
|
||||
val alternateAudio: String?,
|
||||
)
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
|
||||
/**
|
||||
* Cross reference for many to many relationship between [NewsResourceEntity] and [AuthorEntity]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "news_resources_authors",
|
||||
primaryKeys = ["news_resource_id", "author_id"],
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = NewsResourceEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["news_resource_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = AuthorEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["author_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
]
|
||||
)
|
||||
data class NewsResourceAuthorCrossRef(
|
||||
@ColumnInfo(name = "news_resource_id")
|
||||
val newsResourceId: Int,
|
||||
@ColumnInfo(name = "author_id")
|
||||
val authorId: Long,
|
||||
)
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import androidx.room.PrimaryKey
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
/**
|
||||
* Defines an NiA news resource.
|
||||
* It is the child in a 1 to many relationship with [EpisodeEntity]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "news_resources",
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = EpisodeEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["episode_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
]
|
||||
)
|
||||
data class NewsResourceEntity(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
@ColumnInfo(name = "episode_id")
|
||||
val episodeId: Int,
|
||||
val title: String,
|
||||
val content: String,
|
||||
val url: String,
|
||||
@ColumnInfo(name = "publish_date")
|
||||
val publishDate: Instant,
|
||||
val type: String,
|
||||
)
|
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
|
||||
/**
|
||||
* Cross reference for many to many relationship between [NewsResourceEntity] and [TopicEntity]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "news_resources_topics",
|
||||
primaryKeys = ["news_resource_id", "topic_id"],
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = NewsResourceEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["news_resource_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
ForeignKey(
|
||||
entity = TopicEntity::class,
|
||||
parentColumns = ["id"],
|
||||
childColumns = ["topic_id"],
|
||||
onDelete = ForeignKey.CASCADE
|
||||
),
|
||||
]
|
||||
)
|
||||
data class NewsResourceTopicCrossRef(
|
||||
@ColumnInfo(name = "news_resource_id")
|
||||
val newsResourceId: Int,
|
||||
@ColumnInfo(name = "topic_id")
|
||||
val topicId: Int,
|
||||
)
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.entities
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
|
||||
/**
|
||||
* Defines a topic a user may follow.
|
||||
* It has a many to many relationship with [NewsResourceEntity]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "topics",
|
||||
indices = [
|
||||
Index(value = ["name"], unique = true)
|
||||
]
|
||||
)
|
||||
data class TopicEntity(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val description: String,
|
||||
)
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.local.utilities
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import com.google.samples.apps.nowinandroid.data.model.NewsResourceType
|
||||
import kotlinx.datetime.Instant
|
||||
|
||||
class InstantConverter {
|
||||
@TypeConverter
|
||||
fun longToInstant(value: Long?): Instant? =
|
||||
value?.let(Instant::fromEpochMilliseconds)
|
||||
|
||||
@TypeConverter
|
||||
fun instantToLong(instant: Instant?): Long? =
|
||||
instant?.toEpochMilliseconds()
|
||||
}
|
||||
|
||||
class NewsResourceTypeConverter {
|
||||
@TypeConverter
|
||||
fun newsResourceTypeToString(value: NewsResourceType?): String? =
|
||||
value?.let(NewsResourceType::name)
|
||||
|
||||
@TypeConverter
|
||||
fun stringToNewsResourceType(name: String?): NewsResourceType = when (name) {
|
||||
null -> NewsResourceType.Unknown
|
||||
else -> NewsResourceType.values()
|
||||
.firstOrNull { type -> type.name == name }
|
||||
?: NewsResourceType.Unknown
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.model
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.AuthorEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.EpisodeAuthorCrossRef
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.EpisodeEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceEntity
|
||||
|
||||
/**
|
||||
* External data layer representation of an NiA episode
|
||||
*/
|
||||
data class Episode(
|
||||
@Embedded
|
||||
val entity: EpisodeEntity,
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "episode_id"
|
||||
)
|
||||
val newsResources: List<NewsResourceEntity>,
|
||||
@Relation(
|
||||
parentColumn = "episode_id",
|
||||
entityColumn = "author_id",
|
||||
associateBy = Junction(EpisodeAuthorCrossRef::class)
|
||||
)
|
||||
val authors: List<AuthorEntity>
|
||||
)
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.model
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.AuthorEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.EpisodeEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceAuthorCrossRef
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceEntity
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceTopicCrossRef
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.TopicEntity
|
||||
|
||||
/**
|
||||
* External data layer representation of a fully populated NiA news resource
|
||||
*/
|
||||
data class NewsResource(
|
||||
@Embedded
|
||||
val entity: NewsResourceEntity,
|
||||
@Relation(
|
||||
parentColumn = "episode_id",
|
||||
entityColumn = "id"
|
||||
)
|
||||
val episode: EpisodeEntity,
|
||||
@Relation(
|
||||
parentColumn = "news_resource_id",
|
||||
entityColumn = "author_id",
|
||||
associateBy = Junction(NewsResourceAuthorCrossRef::class)
|
||||
)
|
||||
val authors: List<AuthorEntity>,
|
||||
@Relation(
|
||||
parentColumn = "news_resource_id",
|
||||
entityColumn = "topic_id",
|
||||
associateBy = Junction(NewsResourceTopicCrossRef::class)
|
||||
)
|
||||
val topics: List<TopicEntity>
|
||||
)
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.model
|
||||
|
||||
/**
|
||||
* Type for [NewsResource]
|
||||
*/
|
||||
enum class NewsResourceType(
|
||||
val displayText: String,
|
||||
// TODO: descriptions should probably be string resources
|
||||
val description: String
|
||||
) {
|
||||
Video(
|
||||
displayText = "Video 📺",
|
||||
description = "A video published on YouTube"
|
||||
),
|
||||
APIChange(
|
||||
displayText = "API change",
|
||||
description = "An addition, deprecation or change to the Android platform APIs."
|
||||
),
|
||||
Article(
|
||||
displayText = "Article 📚",
|
||||
description = "An article, typically on Medium or the official Android blog"
|
||||
),
|
||||
Codelab(
|
||||
displayText = "Codelab",
|
||||
description = "A new or updated codelab"
|
||||
),
|
||||
Podcast(
|
||||
displayText = "Podcast 🎙",
|
||||
description = "A podcast"
|
||||
),
|
||||
Docs(
|
||||
displayText = "Docs 📑",
|
||||
description = "A new or updated piece of documentation"
|
||||
),
|
||||
Event(
|
||||
displayText = "Event 📆",
|
||||
description = "Information about a developer event e.g. Android Developer Summit"
|
||||
),
|
||||
DAC(
|
||||
displayText = "DAC",
|
||||
description = "Android version features - Information about features in an Android"
|
||||
),
|
||||
Unknown(
|
||||
displayText = "Unknown",
|
||||
description = "Unknown"
|
||||
)
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.network
|
||||
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.AuthorEntity
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Network representation of [AuthorEntity]
|
||||
*/
|
||||
@Serializable
|
||||
data class NetworkAuthor(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val imageUrl: String,
|
||||
)
|
||||
|
||||
fun NetworkAuthor.asEntity() = AuthorEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
imageUrl = imageUrl
|
||||
)
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.network
|
||||
|
||||
import androidx.room.PrimaryKey
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.EpisodeEntity
|
||||
import com.google.samples.apps.nowinandroid.data.network.utilities.InstantSerializer
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Network representation of [EpisodeEntity] when fetched from /networkepisodes
|
||||
*/
|
||||
@Serializable
|
||||
data class NetworkEpisode(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
val name: String,
|
||||
@Serializable(InstantSerializer::class)
|
||||
val publishDate: Instant,
|
||||
val alternateVideo: String?,
|
||||
val alternateAudio: String?,
|
||||
val newsResources: List<Int> = listOf(),
|
||||
val authors: List<Int> = listOf(),
|
||||
)
|
||||
|
||||
/**
|
||||
* Network representation of [EpisodeEntity] when fetched from /networkepisodes{id}
|
||||
*/
|
||||
@Serializable
|
||||
data class NetworkEpisodeExpanded(
|
||||
@PrimaryKey
|
||||
val id: Int,
|
||||
val name: String,
|
||||
@Serializable(InstantSerializer::class)
|
||||
val publishDate: Instant,
|
||||
val alternateVideo: String,
|
||||
val alternateAudio: String,
|
||||
val newsResources: List<NetworkNewsResource> = listOf(),
|
||||
val authors: List<NetworkAuthor> = listOf(),
|
||||
)
|
||||
|
||||
fun NetworkEpisode.asEntity() = EpisodeEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
publishDate = publishDate,
|
||||
alternateVideo = alternateVideo,
|
||||
alternateAudio = alternateAudio,
|
||||
)
|
||||
|
||||
fun NetworkEpisodeExpanded.asEntity() = EpisodeEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
publishDate = publishDate,
|
||||
alternateVideo = alternateVideo,
|
||||
alternateAudio = alternateAudio,
|
||||
)
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.network
|
||||
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.NewsResourceEntity
|
||||
import com.google.samples.apps.nowinandroid.data.network.utilities.InstantSerializer
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Network representation of [NewsResourceEntity] when fetched from /networkresources
|
||||
*/
|
||||
@Serializable
|
||||
data class NetworkNewsResource(
|
||||
val id: Int,
|
||||
val episodeId: Int,
|
||||
val title: String,
|
||||
val content: String,
|
||||
val url: String,
|
||||
@Serializable(InstantSerializer::class)
|
||||
val publishDate: Instant,
|
||||
val type: String,
|
||||
val authors: List<Int> = listOf(),
|
||||
val topics: List<Int> = listOf(),
|
||||
)
|
||||
|
||||
/**
|
||||
* Network representation of [NewsResourceEntity] when fetched from /networkresources{id}
|
||||
*/
|
||||
@Serializable
|
||||
data class NetworkNewsResourceExpanded(
|
||||
val id: Int,
|
||||
val episodeId: Int,
|
||||
val title: String,
|
||||
val content: String,
|
||||
val url: String,
|
||||
@Serializable(InstantSerializer::class)
|
||||
val publishDate: Instant,
|
||||
val type: String,
|
||||
val authors: List<NetworkAuthor> = listOf(),
|
||||
val topics: List<NetworkTopic> = listOf(),
|
||||
)
|
||||
|
||||
fun NetworkNewsResource.asEntity() = NewsResourceEntity(
|
||||
id = id,
|
||||
episodeId = episodeId,
|
||||
title = title,
|
||||
content = content,
|
||||
url = url,
|
||||
publishDate = publishDate,
|
||||
type = type,
|
||||
)
|
||||
|
||||
fun NetworkNewsResourceExpanded.asEntity() = NewsResourceEntity(
|
||||
id = id,
|
||||
episodeId = episodeId,
|
||||
title = title,
|
||||
content = content,
|
||||
url = url,
|
||||
publishDate = publishDate,
|
||||
type = type,
|
||||
)
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.network
|
||||
|
||||
import com.google.samples.apps.nowinandroid.data.local.entities.TopicEntity
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Network representation of [TopicEntity]
|
||||
*/
|
||||
@Serializable
|
||||
data class NetworkTopic(
|
||||
val id: Int,
|
||||
val name: String = "",
|
||||
val description: String = "",
|
||||
)
|
||||
|
||||
fun NetworkTopic.asEntity() = TopicEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
description = description
|
||||
)
|
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.network
|
||||
|
||||
/**
|
||||
* Interface representing network calls to the NIA backend
|
||||
*/
|
||||
interface NiANetwork {
|
||||
suspend fun getNewsResources(): List<NetworkNewsResource>
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.fake
|
||||
|
||||
import com.google.samples.apps.nowinandroid.di.DefaultNiaDispatchers
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.junit.Before
|
||||
|
||||
class FakeNewsRepositoryTest {
|
||||
|
||||
private lateinit var subject: FakeNewsRepository
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
subject = FakeNewsRepository(
|
||||
// TODO: Create test-specific NiaDispatchers
|
||||
dispatchers = DefaultNiaDispatchers(),
|
||||
networkJson = Json { ignoreUnknownKeys = true }
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.samples.apps.nowinandroid.data.network
|
||||
|
||||
import com.google.samples.apps.nowinandroid.data.model.NewsResourceType
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class NetworkEntityKtTest {
|
||||
|
||||
@Test
|
||||
fun network_author_can_be_mapped_to_author_entity() {
|
||||
val networkModel = NetworkAuthor(
|
||||
id = 0,
|
||||
name = "Test",
|
||||
imageUrl = "something"
|
||||
)
|
||||
val entity = networkModel.asEntity()
|
||||
|
||||
assertEquals(0, entity.id)
|
||||
assertEquals("Test", entity.name)
|
||||
assertEquals("something", entity.imageUrl)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun network_topic_can_be_mapped_to_topic_entity() {
|
||||
val networkModel = NetworkTopic(
|
||||
id = 0,
|
||||
name = "Test",
|
||||
description = "something"
|
||||
)
|
||||
val entity = networkModel.asEntity()
|
||||
|
||||
assertEquals(0, entity.id)
|
||||
assertEquals("Test", entity.name)
|
||||
assertEquals("something", entity.description)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun network_news_resource_can_be_mapped_to_news_resource_entity() {
|
||||
val networkModel = NetworkNewsResource(
|
||||
id = 0,
|
||||
episodeId = 2,
|
||||
title = "title",
|
||||
content = "content",
|
||||
url = "url",
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
type = NewsResourceType.Article.displayText,
|
||||
)
|
||||
val entity = networkModel.asEntity()
|
||||
|
||||
assertEquals(0, entity.id)
|
||||
assertEquals(2, entity.episodeId)
|
||||
assertEquals("title", entity.title)
|
||||
assertEquals("content", entity.content)
|
||||
assertEquals("url", entity.url)
|
||||
assertEquals(Instant.fromEpochMilliseconds(1), entity.publishDate)
|
||||
assertEquals(NewsResourceType.Article.displayText, entity.type)
|
||||
|
||||
val expandedNetworkModel = NetworkNewsResourceExpanded(
|
||||
id = 0,
|
||||
episodeId = 2,
|
||||
title = "title",
|
||||
content = "content",
|
||||
url = "url",
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
type = NewsResourceType.Article.displayText,
|
||||
)
|
||||
|
||||
val entityFromExpanded = expandedNetworkModel.asEntity()
|
||||
|
||||
assertEquals(0, entityFromExpanded.id)
|
||||
assertEquals(2, entityFromExpanded.episodeId)
|
||||
assertEquals("title", entityFromExpanded.title)
|
||||
assertEquals("content", entityFromExpanded.content)
|
||||
assertEquals("url", entityFromExpanded.url)
|
||||
assertEquals(Instant.fromEpochMilliseconds(1), entityFromExpanded.publishDate)
|
||||
assertEquals(NewsResourceType.Article.displayText, entityFromExpanded.type)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun network_episode_can_be_mapped_to_episode_entity() {
|
||||
val networkModel = NetworkEpisode(
|
||||
id = 0,
|
||||
name = "name",
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
alternateVideo = "alternateVideo",
|
||||
alternateAudio = "alternateAudio",
|
||||
)
|
||||
val entity = networkModel.asEntity()
|
||||
|
||||
assertEquals(0, entity.id)
|
||||
assertEquals("name", entity.name)
|
||||
assertEquals("alternateVideo", entity.alternateVideo)
|
||||
assertEquals("alternateAudio", entity.alternateAudio)
|
||||
assertEquals(Instant.fromEpochMilliseconds(1), entity.publishDate)
|
||||
|
||||
val expandedNetworkModel = NetworkEpisodeExpanded(
|
||||
id = 0,
|
||||
name = "name",
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
alternateVideo = "alternateVideo",
|
||||
alternateAudio = "alternateAudio",
|
||||
)
|
||||
|
||||
val entityFromExpanded = expandedNetworkModel.asEntity()
|
||||
|
||||
assertEquals(0, entityFromExpanded.id)
|
||||
assertEquals("name", entityFromExpanded.name)
|
||||
assertEquals("alternateVideo", entityFromExpanded.alternateVideo)
|
||||
assertEquals("alternateAudio", entityFromExpanded.alternateAudio)
|
||||
assertEquals(Instant.fromEpochMilliseconds(1), entityFromExpanded.publishDate)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue