Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/61 email confirmation timer #22

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ android {
versionName "1.0"

buildConfigField "Boolean", "USE_MOCK_BACKEND_API", 'false'
buildConfigField "String", "BACKEND_API_URL", '""'
buildConfigField "String", "BACKEND_API_URL", '"https://android-course-backend.herokuapp.com/"'

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down Expand Up @@ -54,21 +54,17 @@ android {
dimension "deployment-environment"
applicationIdSuffix ".dev"
versionNameSuffix ".dev"
buildConfigField "String", "BACKEND_API_URL", '""'
}
stage {
dimension "deployment-environment"
applicationIdSuffix ".stage"
versionNameSuffix ".stage"
buildConfigField "String", "BACKEND_API_URL", '""'
}
prod {
dimension "deployment-environment"
versionNameSuffix ".prod"
// Despite the default config, all the variables are specified explicitly here,
// because this product flavor is the most sensitive to errors.
buildConfigField "Boolean", "USE_MOCK_BACKEND_API", 'false'
buildConfigField "String", "BACKEND_API_URL", '""'
}

}
Expand Down
14 changes: 7 additions & 7 deletions app/src/main/java/com/example/mobileapp/data/network/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ package com.example.mobileapp
import com.example.mobileapp.data.network.request.CreateProfileRequest
import com.example.mobileapp.data.network.request.RefreshAuthTokensRequest
import com.example.mobileapp.data.network.request.SignInWithEmailRequest
import com.example.mobileapp.data.network.response.VerificationTokenResponse
import com.example.mobileapp.data.network.response.error.*
import com.example.mobileapp.domain.AuthTokens
import com.example.mobileapp.domain.Post
import com.example.mobileapp.domain.User
import com.haroldadmin.cnradapter.NetworkResponse
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import retrofit2.http.*

interface Api {
@GET("users")
suspend fun getUsers(): NetworkResponse<List<User>, Unit>

@POST("auth/sign-in-email")
@POST("auth/sign-in-with-email")
suspend fun signInWithEmail(
@Body request: SignInWithEmailRequest
): NetworkResponse<AuthTokens, SignInWithEmailErrorResponse>
Expand All @@ -37,13 +34,16 @@ interface Api {
@Query("code") code: String,
@Query("email") email: String?,
@Query("phone_number") phoneNumber: String?
): NetworkResponse<VerificationTokenResponse, VerifyRegistrationCodeErrorResponse>
): NetworkResponse<Unit, VerifyRegistrationCodeErrorResponse>

@PUT("registration/create-profile")
@POST("registration/create-profile")
suspend fun createProfile(
@Body request: CreateProfileRequest
): NetworkResponse<AuthTokens, CreateProfileErrorResponse>
): NetworkResponse<User, CreateProfileErrorResponse>

@POST("posts")
suspend fun getPost(): NetworkResponse<List<Post>, Unit>

@GET("users/get-profile")
suspend fun getProfile(): NetworkResponse<User, Unit>
}
89 changes: 74 additions & 15 deletions app/src/main/java/com/example/mobileapp/data/network/MockApi.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.example.mobileapp.Api
import com.example.mobileapp.data.network.request.CreateProfileRequest
import com.example.mobileapp.data.network.request.RefreshAuthTokensRequest
import com.example.mobileapp.data.network.request.SignInWithEmailRequest
import com.example.mobileapp.data.network.response.VerificationTokenResponse
import com.example.mobileapp.data.network.response.error.*
import com.example.mobileapp.domain.AuthTokens
import com.example.mobileapp.domain.Post
Expand All @@ -16,23 +15,66 @@ import kotlin.random.Random

class MockApi : Api {

private var idCur = 12L
private val userList = mutableListOf(
User(
id = 7,
firstName = "Michael",
lastName = "Lawson",
avatarUrl = "https://reqres.in/img/faces/7-image.jpg",
username = "Michael",
groupName = "Б09.мкн"
),
User(
id = 4,
firstName = "George",
lastName = "VI",
username = "Gosha",
avatarUrl = null,
groupName = null
),
User(
id = 8,
firstName = "Masha",
lastName = "Nazarova",
username = "Mary",
avatarUrl = null,
groupName = null
),
User(
id = 9,
firstName = "Igor",
lastName = "Petrov",
username = "igor95",
avatarUrl = null,
groupName = null
),
User(
id = 10,
firstName = "Masha",
lastName = "Nazarova",
username = "Mary2",
avatarUrl = null,
groupName = null
),
User(
id = 11,
firstName = "Masha",
lastName = "Nazarova",
username = "Mary3",
avatarUrl = null,
groupName = null
)
)

private val randomizer = Random(1337)

override suspend fun getUsers(): NetworkResponse<List<User>, Unit> {
val success = randomizer.nextBoolean()
Timber.d("Try to load users. Success: %s", success)
if (success)
return NetworkResponse.Success(
body = listOf(
User(
id = 7,
firstName = "Michael",
lastName = "Lawson",
avatarUrl = "https://reqres.in/img/faces/7-image.jpg",
username = "Michael",
groupName = "Б09.мкн"
)
),
body = userList,
code = 200
)
if (randomizer.nextBoolean())
Expand All @@ -58,22 +100,39 @@ class MockApi : Api {
}

override suspend fun sendRegistrationVerificationCode(email: String): NetworkResponse<Unit, SendRegistrationVerificationCodeErrorResponse> {
TODO("Not yet implemented")
return NetworkResponse.Success(body = Unit, code = 200)
}

override suspend fun verifyRegistrationCode(
code: String,
email: String?,
phoneNumber: String?
): NetworkResponse<VerificationTokenResponse, VerifyRegistrationCodeErrorResponse> {
): NetworkResponse<Unit, VerifyRegistrationCodeErrorResponse> {
TODO("Not yet implemented")
}

override suspend fun createProfile(request: CreateProfileRequest): NetworkResponse<AuthTokens, CreateProfileErrorResponse> {
TODO("Not yet implemented")
override suspend fun createProfile(request: CreateProfileRequest): NetworkResponse<User, CreateProfileErrorResponse> {
idCur += 1
val newUser = User(
id = idCur,
username = request.username,
firstName = request.firstName,
lastName = request.lastName,
groupName = null,
avatarUrl = null
)
userList.add(newUser)
return NetworkResponse.Success(body = newUser, code = 204)
}

override suspend fun getPost(): NetworkResponse<List<Post>, Unit> {
TODO("Not yet implemented")
}

override suspend fun getProfile(): NetworkResponse<User, Unit> {
return NetworkResponse.Success(
userList[0],
code = 200
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class CreateProfileRequest(
@Json(name = "verification_token") val verificationToken: String,
@Json(name = "first_name") val firstName: String,
@Json(name = "last_name") val lastName: String,
@Json(name = "username") val username: String,
@Json(name = "user_name") val username: String,
@Json(name = "email") val email: String?,
@Json(name = "password") val password: String
)

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package com.example.mobileapp.data.network.response.error

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.example.mobileapp.domain.Error

@JsonClass(generateAdapter = true)
data class CreateProfileErrorResponse(
@Json(name = "non_field_errors") val nonFieldErrors: List<Error>?,
@Json(name = "verification_token") val verificationToken: List<Error>?,
@Json(name = "first_name") val firstName: List<Error>?,
@Json(name = "last_name") val lastName: List<Error>?,
@Json(name = "email") val email: List<Error>?,
@Json(name = "password") val password: List<Error>?,
@Json(name = "username") val username: List<Error>?
@Json(name = "user_name") val username: List<Error>?
)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.example.mobileapp.data.network.response.error

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.example.mobileapp.domain.Error

@JsonClass(generateAdapter = true)
data class RefreshAuthTokensErrorResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.example.mobileapp.data.network.response.error

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.example.mobileapp.domain.Error

@JsonClass(generateAdapter = true)
data class SendRegistrationVerificationCodeErrorResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.example.mobileapp.data.network.response.error

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.example.mobileapp.domain.Error

@JsonClass(generateAdapter = true)
data class SignInWithEmailErrorResponse(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.example.mobileapp.data.network.response.error

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import com.example.mobileapp.domain.Error

@JsonClass(generateAdapter = true)
data class VerifyRegistrationCodeErrorResponse(
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/example/mobileapp/domain/Errors.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
data class Error(
@Json(name = "code") val code: ErrorCode,
@Json(name = "code") val code: Int,
@Json(name = "message") val message: String
)

Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/example/mobileapp/domain/User.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import com.squareup.moshi.JsonClass
data class User(
@Json(name = "id") val id: Long,
@Json(name = "user_name") val username: String,
@Json(name = "avatar") val avatarUrl: String?, // E.g. "https://mydomain.com/user_1_avatar.jpg"
@Json(name = "picture") var avatarUrl: String?, //media.zenfs.com/en-US/homerun/time_72/ad41bb42a3e7be9eb1e32a9f2097b80f", // E.g. "https://mydomain.com/user_1_avatar.jpg"
@Json(name = "first_name") val firstName: String,
@Json(name = "last_name") val lastName: String,
@Json(name = "group_name") val groupName: String?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.example.mobileapp.interactor

import com.example.mobileapp.data.network.response.error.CreateProfileErrorResponse
import com.example.mobileapp.data.network.response.error.SignInWithEmailErrorResponse
import com.example.mobileapp.domain.AuthTokens
import com.example.mobileapp.domain.User
import com.example.mobileapp.repository.AuthRepository
import com.haroldadmin.cnradapter.NetworkResponse
import kotlinx.coroutines.flow.Flow
Expand All @@ -27,6 +29,23 @@ class AuthInteractor @Inject constructor(
return response
}

suspend fun signUpWithPersonalInfo(
firstName: String,
lastName: String,
username: String,
email: String,
password: String
): NetworkResponse<User, CreateProfileErrorResponse> {
val response = authRepository.generateUserByEmailAndPersonalInfo(firstName, lastName,
username, email, password)
when (response) {
is NetworkResponse.Error -> {
Timber.e(response.error)
}
}
return response
}

suspend fun logout() {
authRepository.saveAuthTokens(null)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.mobileapp.interactor

import android.content.res.Resources
import com.example.mobileapp.R
import com.example.mobileapp.domain.User
import com.example.mobileapp.repository.ProfileRepository
import com.haroldadmin.cnradapter.NetworkResponse
import javax.inject.Inject

class ProfileInteractor @Inject constructor(
private val profileRepository: ProfileRepository
) {

suspend fun getProfile() : NetworkResponse<User, Unit> {
val response = profileRepository.getProfile()
when (response) {
is NetworkResponse.Success -> {
response.body.avatarUrl = response.body.avatarUrl ?: "https://s.yimg.com/ny/api/res/1.2/5rmN2CQI90DCby7uM2UefQ--/YXBwaWQ9aGlnaGxhbmRlcjt3PTEyMDA7aD04MDA-/https://s.yimg.com/uu/api/res/1.2/W1dJaYmRHV_PHKDIDmm__Q--~B/aD0xNDAwO3c9MjEwMDthcHBpZD15dGFjaHlvbg--/http://media.zenfs.com/en-US/homerun/time_72/ad41bb42a3e7be9eb1e32a9f2097b80f"
}
}
return response
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,14 @@ class UsersInteractor @Inject constructor(
private val usersRepository: UsersRepository
) {

suspend fun loadUsers() : NetworkResponse<List<User>, Unit> =
usersRepository.getUsers()
suspend fun loadUsers() : NetworkResponse<List<User>, Unit> {
val response = usersRepository.getUsers()
when (response) {
is NetworkResponse.Success -> {
response.body.map { it.avatarUrl = it.avatarUrl ?: "https://s.yimg.com/ny/api/res/1.2/5rmN2CQI90DCby7uM2UefQ--/YXBwaWQ9aGlnaGxhbmRlcjt3PTEyMDA7aD04MDA-/https://s.yimg.com/uu/api/res/1.2/W1dJaYmRHV_PHKDIDmm__Q--~B/aD0xNDAwO3c9MjEwMDthcHBpZD15dGFjaHlvbg--/http://media.zenfs.com/en-US/homerun/time_72/ad41bb42a3e7be9eb1e32a9f2097b80f" }
}
}
return response
}

}
Loading