Skip to content

Commit

Permalink
🎨 Apply refactored code from main
Browse files Browse the repository at this point in the history
  • Loading branch information
paul2126 committed Nov 16, 2023
2 parents f8f949c + 6b455a9 commit 90164e8
Show file tree
Hide file tree
Showing 86 changed files with 2,575 additions and 1,205 deletions.
32 changes: 7 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
# SNU-SWPP-Template
# SpeechBuddy ![top_app_bar_ic](https://github.com/snuhcs-course/swpp-2023-project-team-6/assets/65206075/154ef236-a392-41b1-beba-208cfd44c72c)

You can use the README file to showcase and promote your mobile app. The template provided below is just a starting point. Feel free to craft your README as you see fit.
SpeechBuddy is a AAC(Augmentative and Alternative Communication) app designed to facilitate communication for individuals with speech impairments.<br>
Specific target users are as follows.<br>
- People who needs more direct and straightforward communication methods due to cognitive disabilities (e.g. those with autism spectrum disorders, aphasia...)
- People who are physically unable to produce sounds (e.g. those who had cordectomy, who has severe dysarthria...)<br>

Please note that the README doesn't affect your grade and is not included in documentation(Wiki).
Our app offers two main features: symbol-based communication and text-to-speech functionality. Users can communicate by selecting from a wide range of symbols, including the option to add personalized symbols with pictures. Additionally, SpeechBuddy incorporates next symbol prediction based on user's history, enhancing the efficiency of communication. For users who can type, SpeechBuddy also provides a text-to-speech feature, offering an alternative voice for the user. Overall, SpeechBuddy aims to enhance accessibility and communication for individuals with speech impairments through its versatile and user-friendly features.

# [Your Application Name]

[Short application description here]

![Application Screenshot](path_to_screenshot.png)

## Features

- Feature 1: Brief description
- Feature 2: Brief description
- ...

## Getting Started

### Prerequisites

- Android Studio [version, e.g., 4.2.1]
- Minimum Android SDK Version [e.g., 21]

### Installation

[Installation link here]
You can find more information in our [wiki page](https://github.com/snuhcs-course/swpp-2023-project-team-6/wiki)!
103 changes: 102 additions & 1 deletion backend/entry/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,104 @@
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from rest_framework import status

# Create your tests here.
from entry.models import Symbol
from user.models import User


class SymbolTest(TestCase):

def setUp(self):
self.user = User.objects.create_user(
email='[email protected]',
password='test_password',
nickname='test_nickname'
)
self.tokens = self.login_and_get_tokens()
self.access_token = self.tokens.get('access')
self.refresh_token = self.tokens.get('refresh')

Symbol.objects.create(id=501, text="test1", category=1, created_by=self.user)
Symbol.objects.create(id=502, text="test2", category=2, created_by=self.user)
Symbol.objects.create(id=503, text="test3", category=3, created_by=self.user)

def login_and_get_tokens(self):
data = {
'email': '[email protected]',
'password': 'test_password',
}
response = self.client.post('/user/login/', data)
if response.status_code == status.HTTP_200_OK:
tokens = response.json()
return tokens
return None

def test_favorite_backup_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
# Add some favorites to the user's list
response = self.client.post('/symbol/favorite/backup/?id=501,502,503', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_get_favorite_symbols_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
expected_response = {
'id': 501
}
# Add favorite symbol to check
response = self.client.post('/symbol/favorite/backup/?id=501', **headers)

response = self.client.get('/symbol/favorite/backup/', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(data.get('results')[0], expected_response)

def test_enable_my_symbols_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
# Enable user-created symbols
response = self.client.post('/symbol/enable/?id=501', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_enable_my_symbols_fail_no_such_symbol(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
# Enable user-created symbols
response = self.client.post('/symbol/enable/?id=505', **headers)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

def test_get_my_symbols_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
# Get all of the user-created symbols
self.client.post('/symbol/enable/?id=501', **headers) # since ONLY enabled symbols can be retrieved
response = self.client.get('/symbol/', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(len(data.get('my_symbols')), 1) # since only one symbol is enabled

def test_get_my_specific_symbol_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
# Get all of the user-created symbols
self.client.post('/symbol/enable/?id=501', **headers) # since ONLY enabled symbols can be retrieved
response = self.client.get('/symbol/501/', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertIsNotNone(data.get('my_symbol'))

def test_get_my_specific_symbol_fail_invalid_symbol(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
# Get all of the user-created symbols
response = self.client.get('/symbol/501/', **headers)
# Since symbol 501 is not valid yet
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
65 changes: 64 additions & 1 deletion backend/setup/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,66 @@
from django.test import TestCase
from rest_framework import status

from user.models import User


class SettingsTest(TestCase):

def setUp(self):
self.user = User.objects.create_user(
email='[email protected]',
password='test_password',
nickname='test_nickname'
)
self.tokens = self.login_and_get_tokens()
self.access_token = self.tokens.get('access')
self.refresh_token = self.tokens.get('refresh')

def login_and_get_tokens(self):
data = {
'email': '[email protected]',
'password': 'test_password',
}
response = self.client.post('/user/login/', data)
if response.status_code == status.HTTP_200_OK:
tokens = response.json()
return tokens
return None

def test_settings_backup_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
data = {
'display_mode': 0,
'default_menu': 1
}
# when attempting backup for the first time
response = self.client.post('/setting/backup/', data, **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)

# when attempting backup repetitively
data = {
'display_mode': 1,
'default_menu': 0
}
response = self.client.post('/setting/backup/', data, **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_get_settings_success(self):
headers = {
'HTTP_AUTHORIZATION': f'Bearer {self.access_token}'
}
response = self.client.get('/setting/backup/', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()
self.assertEqual(data['display_mode'], 0) # 0 is the default value
self.assertEqual(data['default_menu'], 0) # 0 is the default value








# Create your tests here.
3 changes: 1 addition & 2 deletions backend/user/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,7 @@ class Meta:
fields = (
'id',
'email',
'nickname',
'updated_at',
'nickname'
)


Expand Down
5 changes: 2 additions & 3 deletions backend/user/test_views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.test import TestCase
from rest_framework import status
from rest_framework.utils import json

from user.models import User, EmailVerification

Expand Down Expand Up @@ -51,7 +50,7 @@ def test_get_profile_success(self):
}
response = self.client.get('/user/profile/', **headers)
self.assertEqual(response.status_code, status.HTTP_200_OK)
data = response.json()['user']
data = response.json()
self.assertEqual(self.user.email, data['email'])
self.assertEqual(self.user.nickname, data['nickname'])

Expand Down Expand Up @@ -94,7 +93,7 @@ def test_change_nickname_success(self):

# Call get-profile API to check whether the value change is applied
response = self.client.get('/user/profile/', **headers)
self.assertEqual(data['nickname'], response.json()['user']['nickname'])
self.assertEqual(data['nickname'], response.json()['nickname'])

def test_change_password_success(self):
headers = {
Expand Down
2 changes: 1 addition & 1 deletion backend/user/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def normalize_email(email):

def generate_code():
LENGTH = 6
seed = string.ascii_letters + string.digits
seed = string.digits
code = ""

for i in range(LENGTH):
Expand Down
3 changes: 1 addition & 2 deletions backend/user/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,7 @@ class UserProfileView(APIView):
def get(self, request):
user = request.user
serialized_user = UserProfileSerializer(user).data
response_data = {"user": serialized_user}
return Response(response_data, status=status.HTTP_200_OK)
return Response(serialized_user, status=status.HTTP_200_OK)


class PasswordUpdateView(APIView):
Expand Down
7 changes: 6 additions & 1 deletion frontend/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ dependencies {
// Gson
implementation("com.google.code.gson:gson:2.9.0")

// DataStore
val dataStoreVersion = "1.0.0-alpha06"
implementation("androidx.datastore:datastore-preferences:$dataStoreVersion")
implementation("androidx.datastore:datastore-preferences-core:$dataStoreVersion")

// Room
val roomVersion = "2.6.0"
implementation("androidx.room:room-ktx:$roomVersion")
Expand All @@ -130,7 +135,7 @@ dependencies {
implementation("com.google.dagger:hilt-android:$hiltVersion")
kapt("com.google.dagger:hilt-compiler:$hiltVersion")

implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
implementation("androidx.hilt:hilt-navigation-compose:1.1.0")

// MockK
val mockkVersion = "1.13.8"
Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".MainApplication"
android:name=".BaseApplication"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
Expand All @@ -16,8 +16,9 @@
android:theme="@style/Theme.SpeechBuddy"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity android:name=".HomeActivity" />
<activity
android:name=".MainActivity"
android:name=".AuthActivity"
android:exported="true"
android:theme="@style/Theme.SpeechBuddy">
<intent-filter>
Expand Down
50 changes: 50 additions & 0 deletions frontend/app/src/main/java/com/example/speechbuddy/AuthActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.example.speechbuddy

import android.content.Intent
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.core.view.WindowCompat
import com.example.speechbuddy.compose.SpeechBuddyAuth
import com.example.speechbuddy.ui.SpeechBuddyTheme
import com.example.speechbuddy.viewmodel.LoginViewModel
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class AuthActivity : BaseActivity() {

private val loginViewModel: LoginViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

// Displaying edge-to-edge
WindowCompat.setDecorFitsSystemWindows(window, false)

subscribeObservers()
checkPreviousAuthUser()

setContent {
SpeechBuddyTheme {
SpeechBuddyAuth()
}
}
}

private fun subscribeObservers() {
sessionManager.isAuthorized.observe(this) { isAuthorized ->
if (isAuthorized) navHomeActivity()
}
}

private fun navHomeActivity() {
val intent = Intent(this, HomeActivity::class.java)
startActivity(intent)
finish()
}

private fun checkPreviousAuthUser() {
loginViewModel.checkPreviousUser()
}

}
12 changes: 12 additions & 0 deletions frontend/app/src/main/java/com/example/speechbuddy/BaseActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.speechbuddy

import androidx.appcompat.app.AppCompatActivity
import com.example.speechbuddy.domain.SessionManager
import javax.inject.Inject

abstract class BaseActivity : AppCompatActivity() {

@Inject
lateinit var sessionManager: SessionManager

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.speechbuddy

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class BaseApplication : Application()
Loading

0 comments on commit 90164e8

Please sign in to comment.