commit
2c9fcebab6
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.database.model
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.Episode
|
||||
|
||||
/**
|
||||
* External data layer representation of an NiA episode
|
||||
*/
|
||||
data class PopulatedEpisode(
|
||||
@Embedded
|
||||
val entity: EpisodeEntity,
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "episode_id"
|
||||
)
|
||||
val newsResources: List<NewsResourceEntity>,
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "id",
|
||||
associateBy = Junction(
|
||||
value = EpisodeAuthorCrossRef::class,
|
||||
parentColumn = "episode_id",
|
||||
entityColumn = "author_id",
|
||||
)
|
||||
)
|
||||
val authors: List<AuthorEntity>
|
||||
)
|
||||
|
||||
fun PopulatedEpisode.asExternalModel() = Episode(
|
||||
id = entity.id,
|
||||
name = entity.name,
|
||||
publishDate = entity.publishDate,
|
||||
alternateVideo = entity.alternateVideo,
|
||||
alternateAudio = entity.alternateAudio,
|
||||
newsResources = newsResources.map(NewsResourceEntity::asExternalModel),
|
||||
authors = authors.map(AuthorEntity::asExternalModel)
|
||||
)
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.database.model
|
||||
|
||||
import androidx.room.Embedded
|
||||
import androidx.room.Junction
|
||||
import androidx.room.Relation
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
|
||||
|
||||
/**
|
||||
* External data layer representation of a fully populated NiA news resource
|
||||
*/
|
||||
data class PopulatedNewsResource(
|
||||
@Embedded
|
||||
val entity: NewsResourceEntity,
|
||||
@Relation(
|
||||
parentColumn = "episode_id",
|
||||
entityColumn = "id"
|
||||
)
|
||||
val episode: EpisodeEntity,
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "id",
|
||||
associateBy = Junction(
|
||||
value = NewsResourceAuthorCrossRef::class,
|
||||
parentColumn = "news_resource_id",
|
||||
entityColumn = "author_id",
|
||||
)
|
||||
)
|
||||
val authors: List<AuthorEntity>,
|
||||
@Relation(
|
||||
parentColumn = "id",
|
||||
entityColumn = "id",
|
||||
associateBy = Junction(
|
||||
value = NewsResourceTopicCrossRef::class,
|
||||
parentColumn = "news_resource_id",
|
||||
entityColumn = "topic_id",
|
||||
)
|
||||
)
|
||||
val topics: List<TopicEntity>
|
||||
)
|
||||
|
||||
fun PopulatedNewsResource.asExternalModel() = NewsResource(
|
||||
id = entity.id,
|
||||
episodeId = entity.episodeId,
|
||||
title = entity.title,
|
||||
content = entity.content,
|
||||
url = entity.url,
|
||||
publishDate = entity.publishDate,
|
||||
type = entity.type,
|
||||
authors = authors.map(AuthorEntity::asExternalModel),
|
||||
topics = topics.map(TopicEntity::asExternalModel)
|
||||
)
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.domain.model
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.database.model.AuthorEntity
|
||||
import com.google.samples.apps.nowinandroid.core.network.model.NetworkAuthor
|
||||
|
||||
fun NetworkAuthor.asEntity() = AuthorEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
imageUrl = imageUrl
|
||||
)
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.domain.model
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.database.model.EpisodeEntity
|
||||
import com.google.samples.apps.nowinandroid.core.network.model.NetworkEpisode
|
||||
import com.google.samples.apps.nowinandroid.core.network.model.NetworkEpisodeExpanded
|
||||
|
||||
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,41 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.domain.model
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.database.model.NewsResourceEntity
|
||||
import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResource
|
||||
import com.google.samples.apps.nowinandroid.core.network.model.NetworkNewsResourceExpanded
|
||||
|
||||
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,27 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.domain.model
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
|
||||
import com.google.samples.apps.nowinandroid.core.network.model.NetworkTopic
|
||||
|
||||
fun NetworkTopic.asEntity() = TopicEntity(
|
||||
id = id,
|
||||
name = name,
|
||||
description = description,
|
||||
followed = followed
|
||||
)
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.database.model
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.Author
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.Episode
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class PopulatedEpisodeKtTest {
|
||||
@Test
|
||||
fun populated_episode_can_be_mapped_to_episode() {
|
||||
val populatedEpisode = PopulatedEpisode(
|
||||
entity = EpisodeEntity(
|
||||
id = 0,
|
||||
name = "Test",
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
alternateAudio = "audio",
|
||||
alternateVideo = "video"
|
||||
),
|
||||
newsResources = listOf(
|
||||
NewsResourceEntity(
|
||||
id = 1,
|
||||
episodeId = 0,
|
||||
title = "news",
|
||||
content = "Hilt",
|
||||
url = "url",
|
||||
type = Video,
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
)
|
||||
),
|
||||
authors = listOf(
|
||||
AuthorEntity(
|
||||
id = 2,
|
||||
name = "name",
|
||||
imageUrl = "imageUrl"
|
||||
)
|
||||
),
|
||||
)
|
||||
val episode = populatedEpisode.asExternalModel()
|
||||
|
||||
assertEquals(
|
||||
Episode(
|
||||
id = 0,
|
||||
name = "Test",
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
alternateAudio = "audio",
|
||||
alternateVideo = "video",
|
||||
newsResources = listOf(
|
||||
NewsResource(
|
||||
id = 1,
|
||||
episodeId = 0,
|
||||
title = "news",
|
||||
content = "Hilt",
|
||||
url = "url",
|
||||
type = Video,
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
authors = listOf(),
|
||||
topics = listOf()
|
||||
)
|
||||
),
|
||||
authors = listOf(
|
||||
Author(
|
||||
id = 2,
|
||||
name = "name",
|
||||
imageUrl = "imageUrl"
|
||||
)
|
||||
),
|
||||
),
|
||||
episode
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.database.model
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.Author
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.NewsResource
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.Topic
|
||||
import kotlinx.datetime.Instant
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class PopulatedNewsResourceKtTest {
|
||||
@Test
|
||||
fun populated_news_resource_can_be_mapped_to_news_resource() {
|
||||
val populatedNewsResource = PopulatedNewsResource(
|
||||
entity = NewsResourceEntity(
|
||||
id = 1,
|
||||
episodeId = 0,
|
||||
title = "news",
|
||||
content = "Hilt",
|
||||
url = "url",
|
||||
type = Video,
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
),
|
||||
episode = EpisodeEntity(
|
||||
id = 4,
|
||||
name = "episode 4",
|
||||
publishDate = Instant.fromEpochMilliseconds(2),
|
||||
alternateAudio = "audio",
|
||||
alternateVideo = "video",
|
||||
),
|
||||
authors = listOf(
|
||||
AuthorEntity(
|
||||
id = 2,
|
||||
name = "name",
|
||||
imageUrl = "imageUrl"
|
||||
)
|
||||
),
|
||||
topics = listOf(
|
||||
TopicEntity(
|
||||
id = 3,
|
||||
name = "name",
|
||||
description = "description",
|
||||
followed = true,
|
||||
)
|
||||
),
|
||||
)
|
||||
val newsResource = populatedNewsResource.asExternalModel()
|
||||
|
||||
assertEquals(
|
||||
NewsResource(
|
||||
id = 1,
|
||||
episodeId = 0,
|
||||
title = "news",
|
||||
content = "Hilt",
|
||||
url = "url",
|
||||
type = Video,
|
||||
publishDate = Instant.fromEpochMilliseconds(1),
|
||||
authors = listOf(
|
||||
Author(
|
||||
id = 2,
|
||||
name = "name",
|
||||
imageUrl = "imageUrl"
|
||||
)
|
||||
),
|
||||
topics = listOf(
|
||||
Topic(
|
||||
id = 3,
|
||||
name = "name",
|
||||
description = "description",
|
||||
followed = true,
|
||||
)
|
||||
)
|
||||
),
|
||||
newsResource
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.model.data
|
||||
|
||||
/**
|
||||
* External data layer representation of an NiA Author
|
||||
*/
|
||||
data class Author(
|
||||
val id: Int,
|
||||
val name: String,
|
||||
val imageUrl: String,
|
||||
)
|
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2022 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.core.network.model.util
|
||||
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType
|
||||
import com.google.samples.apps.nowinandroid.core.model.data.asNewsResourceType
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind.STRING
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
object NewsResourceTypeSerializer : KSerializer<NewsResourceType> {
|
||||
override fun deserialize(decoder: Decoder): NewsResourceType =
|
||||
decoder.decodeString().asNewsResourceType()
|
||||
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
|
||||
serialName = "type",
|
||||
kind = STRING
|
||||
)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: NewsResourceType) =
|
||||
encoder.encodeString(value.name)
|
||||
}
|
Loading…
Reference in new issue