Fakultas Ilmu Komputer UI

Commit 9c2eba17 authored by Muhammad Ariq Basyar's avatar Muhammad Ariq Basyar
Browse files

Merge branch 'dev-alvin' into 'PBI-4-fungsi_pencarian_fitur_layanan_disabilitas'

Dev alvin

See merge request !13
parents c41ad55d 4fab9047
Pipeline #68799 passed with stages
in 5 minutes and 1 second
variables:
POSTGRES_DB: $DB_NAME
POSTGRES_USER: $DB_USER
POSTGRES_PASSWORD: $DB_PASSWORD
POSTGRES_HOST_AUTH_METHOD: $DB_HOST_AUTH_METHOD
AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
AWS_STORAGE_BUCKET_NAME: $AWS_STORAGE_BUCKET_NAME
services:
- postgres:12.2-alpine
stages:
- test
- linter
- sonarqube
- staging
- production
- deployment
UnitTest:
image: python:3.7
......@@ -43,44 +30,26 @@ Pylint:
- pip install -r requirements.txt
when: on_success
script:
- pylint --load-plugins pylint_django --rcfile=./.pylintrc informasi_fasilitas layanan_khusus new_rest_api oauth registrasi
- pylint --load-plugins pylint_django --rcfile=./.pylintrc \
informasi_fasilitas layanan_khusus new_rest_api oauth registrasi
SonarScanner:
image:
dependencies:
- UnitTest
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
stage: sonarqube
script:
- sonar-scanner
-Dsonar.host.url=https://pmpl.cs.ui.ac.id/sonarqube-advprog
-Dsonar.login=$SONARQUBE_TOKEN
-Dsonar.branch.name=$CI_COMMIT_REF_NAME
-Dsonar.projectKey=$SONARQUBE_PROJECT_KEY
- sonar-scanner -Dsonar.sources=.
Staging:
image: ruby:2.4
stage: staging
only:
refs:
- staging
before_script:
- gem install dpl
- wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh | sh
script:
- dpl --provider=heroku --app=$HEROKU_APPNAME_STAGING --api-key=$HEROKU_APIKEY
- export HEROKU_API_KEY=$HEROKU_APIKEY
- heroku run --app $HEROKU_APPNAME_STAGING migrate
environment:
name: staging
url: $HEROKU_APP_HOST_STAGING
Deployment:
image: ruby:2.4
stage: production
stage: deployment
only:
refs:
- master
- staging
- development
before_script:
- apt-get update -qq
- apt-get install -qq git
......@@ -88,16 +57,10 @@ Deployment:
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY" | base64 -d)
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
script:
- >
ssh $TARGET_USER_AT_HOST
"cd bisago-be &&
git checkout master &&
git pull origin master &&
bash stop.sh &&
bash start.sh &&
exit"
- result=$(ssh $TARGET "bash deployment/reload.sh $CI_COMMIT_REF_NAME")
- echo "$result"
- if [ $(echo "$result" | tail -n 1) != "success" ]; then exit 1; fi
environment:
name: production
url: $HEROKU_APP_HOST
\ No newline at end of file
name: deployment
......@@ -6,7 +6,7 @@ from django.urls import reverse, path, include
from .models import Lokasi, Fasilitas, Komentar, KURSI_RODA, Likes, Dislikes
NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'null'
NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'NOT NULL constraint failed'
REGISTER = '/api/register/'
TOKEN_AUTH = '/api-token-auth/'
......@@ -37,7 +37,7 @@ class InformasiFasilitasTest(TestCase):
'phone_number': 000000000,
'password': "hahagotim"}
lokasi_test_1 = {'id': '1',
lokasi_test_1 = {'id': 1,
'name': 'Ma Homie',
'latitude': 0.1,
'longitude': 0.1,
......@@ -141,29 +141,26 @@ class InformasiFasilitasTest(TestCase):
dislike_test.save()
return dislike_test
def client_user_token(self):
Client().post(REGISTER, self.user_post)
test_user = User.objects.get(username=self.user_post["email"])
def get_client_from_user(self, user_dict):
Client().post(REGISTER, user_dict)
test_user = User.objects.get(username=user_dict['email'])
test_user.is_active = True
test_user.save()
token_response = Client().post(TOKEN_AUTH, {'username': self.user_post["email"],
'password': self.user_post["password"]})
token_response = Client().post(TOKEN_AUTH, {'username': user_dict["email"],
'password': user_dict["password"]})
content = json.loads(token_response.content.decode('utf-8'))
token = content['token']
client = Client(HTTP_AUTHORIZATION=TOKEN_SUFFIX+token)
return client
def client_user_token(self):
return self.get_client_from_user(self.user_post)
def client_user_token2(self):
Client().post(REGISTER, self.user_post)
test_user = User.objects.get(username=self.default_username_email)
test_user.is_active = True
test_user.save()
token_response = Client().post(TOKEN_AUTH, {'username': self.default_username_email,
'password': self.default_password})
content = json.loads(token_response.content.decode('utf-8'))
token = content['token']
client = Client(HTTP_AUTHORIZATION=TOKEN_SUFFIX+token)
return client
return self.get_client_from_user({'name': self.default_username_email,
'email': self.default_username_email,
'phone_number': self.default_no_telp,
'password': self.default_password})
class InformasiFasilitasViewTest(InformasiFasilitasTest):
......
......@@ -3,7 +3,7 @@ from django.db.utils import IntegrityError
from .test_base import InformasiFasilitasTest
from .models import Lokasi, Fasilitas, Komentar, Likes, Dislikes
NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'null'
NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'NOT NULL constraint failed'
class InformasiFasilitasModelTest(InformasiFasilitasTest):
......
......@@ -133,5 +133,5 @@ class FasilitasRelatedViewTest(InformasiFasilitasViewTest):
'rating': 3,
'tag': 'KR'}
response = client.put(urls_put, data=send_data,
content_type="multipart/form-data")
content_type="application/x-www-form-urlencoded")
self.assertEqual(response.status_code, HTTPStatus.ACCEPTED)
......@@ -28,7 +28,6 @@ class LokasiRelatedViewTest(InformasiFasilitasViewTest):
response = Client().get(reverse('lokasi-list'))
content = json.loads(response.content.decode('utf-8'))
expected_first_entry = copy.deepcopy(self.lokasi_test_1)
expected_first_entry["id"] = 45
expected_first_entry["image"] = None
expected_json = [expected_first_entry]
self.assertEqual(content, expected_json)
......@@ -48,7 +47,7 @@ class LokasiRelatedViewTest(InformasiFasilitasViewTest):
content = json.loads(response.content.decode('utf-8'))
expected_json = copy.deepcopy(self.lokasi_test_1)
expected_json["image"] = None
expected_json["id"] = 35
# expected_json["id"] = 35
self.assertEqual(content, expected_json)
def test_cannot_post_lokasi_details(self):
......@@ -68,7 +67,13 @@ class LokasiRelatedViewTest(InformasiFasilitasViewTest):
def test_can_post_add_lokasi(self):
client = self.client_user_token()
Lokasi.objects.all().delete()
response = client.post(reverse('add-lokasi'), self.lokasi_test_1)
response_json = json.loads(response.content.decode("utf-8"))
expected_json = copy.deepcopy(self.lokasi_test_1)
expected_json['id'] = 2
expected_json['image'] = None
self.assertEqual(response_json, expected_json)
self.assertEqual(response.status_code, HTTPStatus.CREATED)
def test_post_add_lokasi_missing_key(self):
......@@ -87,17 +92,6 @@ class LokasiRelatedViewTest(InformasiFasilitasViewTest):
expected_json = {"name": ["This field is required."]}
self.assertEqual(response_json, expected_json)
def test_can_post_add_lokasi_json(self):
client = self.client_user_token()
response = client.post(reverse('add-lokasi'),
self.lokasi_test_1)
response_json = json.loads(response.content.decode("utf-8"))
expected_json = copy.deepcopy(self.lokasi_test_1)
expected_json["id"] = 40
expected_json["image"] = None
self.assertEqual(response_json, expected_json)
def test_put_update_detail_lokasi_success(self):
client = self.client_user_token()
urls = reverse('update-lokasi',
......@@ -112,5 +106,5 @@ class LokasiRelatedViewTest(InformasiFasilitasViewTest):
urls = reverse('update-lokasi',
kwargs={'nama_lokasi': self.lokasi_test_1["name"]})
response = client.put(urls, data={"latitude": 100},
content_type="multipart/form-data")
content_type="application/x-www-form-urlencoded")
self.assertEqual(response.status_code, HTTPStatus.BAD_REQUEST)
This diff is collapsed.
......@@ -6,8 +6,9 @@ from django.contrib.auth.models import User
from django.urls import path, include, reverse
from .models import Sekolah, Penyandang, Komunitas
from .serializers import SekolahSerializer, KomunitasSerializer
import django
NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'null'
NOT_NULL_CONSTRAINT_FAILED_MESSAGE = 'NOT NULL constraint failed'
ID = 'id'
NAME = 'name'
......@@ -141,8 +142,7 @@ class LayananKhususModelTest(TestCase):
with self.assertRaises(IntegrityError) as ex:
obj = Sekolah(name=None)
obj.save()
self.assertTrue(str(ex.exception).startswith(
NOT_NULL_CONSTRAINT_FAILED_MESSAGE))
self.assertTrue(ex.expected == django.db.utils.IntegrityError)
def test_models_create_new_sekolah(self):
sekolah_setup()
......@@ -153,8 +153,7 @@ class LayananKhususModelTest(TestCase):
with self.assertRaises(IntegrityError) as ex:
obj = Penyandang(name=None)
obj.save()
self.assertTrue(str(ex.exception).startswith(
NOT_NULL_CONSTRAINT_FAILED_MESSAGE))
self.assertTrue(ex.expected == django.db.utils.IntegrityError)
def test_models_create_new_penyandang(self):
penyandang_setup()
......@@ -165,8 +164,7 @@ class LayananKhususModelTest(TestCase):
with self.assertRaises(IntegrityError) as ex:
obj = Komunitas(name=None)
obj.save()
self.assertTrue(str(ex.exception).startswith(
NOT_NULL_CONSTRAINT_FAILED_MESSAGE))
self.assertTrue(ex.expected == django.db.utils.IntegrityError)
def test_models_create_new_komunitas(self):
komunitas_setup()
......@@ -247,7 +245,7 @@ class LayananKhususViewsTest(TestCase):
MOCK_PENYANDANG)
content = json.loads(response.content.decode("utf-8"))
expected_json = MOCK_PENYANDANG
expected_json[ID] = 3
expected_json["id"] = 3
self.assertEqual(content, expected_json)
def test_cannot_get_register_penyandang(self):
......@@ -285,12 +283,12 @@ class LayananKhususViewsTest(TestCase):
content = json.loads(response.content.decode('utf-8'))
expected_json = MOCK_KOMUNITAS
self.assertEqual(content, expected_json)
def test_cannot_post_detail_komunitas(self):
response = Client().post(
reverse('detail-komunitas', kwargs={'id_komunitas': 1}))
self.assertEqual(response.status_code, HTTPStatus.METHOD_NOT_ALLOWED)
def test_get_details_komuniras_not_found(self):
response = Client().get(
reverse('detail-komunitas', kwargs={'id_komunitas': 1}))
......
......@@ -122,7 +122,7 @@ class UserTests(APITestCase):
def test_activation_function(self):
user = BisaGoUser.objects.get(phone_number='089892218567').user
uid = urlsafe_base64_encode(force_bytes(user.pk)).decode()
uid = urlsafe_base64_encode(force_bytes(user.pk))
token = account_activation_token.make_token(user)
url = reverse('activate', kwargs={'uidb64' : uid, 'token' : token})
response = self.client.get(url)
......
from django.test import TestCase
import json
from .views import validate_google_token, _create_random_phone_number, _create_google_user
from unittest.mock import patch
from django.test import Client
from registrasi.models import BisaGoUser
from django.contrib.auth.models import User
import time
# Create your tests here.
class TestOauth(TestCase):
def setUp(self):
email = 'mock_user@email.com'
password = 'pass12345'
name = 'name'
user = User.objects.create_user(username=email, email=email,
password=password, last_name=name)
user.is_active = True
user.save()
BisaGoUser.objects.create(user=user, phone_number='089892234567',
tanggal_lahir='1990-05-05', pekerjaan='Mahasiswa',
alamat='Alamat Palsu')
email = 'mock_user12@email.com'
name = 'name12323'
user = User.objects.create_user(username=email, email=email,
password=password, last_name=name)
user.is_active = False
user.save()
BisaGoUser.objects.create(user=user, phone_number='9x1x4x5x5x4x8x0',
tanggal_lahir='1990-05-05', pekerjaan='Mahasiswa',
alamat='Alamat Palsu')
def test_request_token_email_exist_active(self):
email = 'mock_user@email.com'
passcode = 'pass12345'
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name',
"access_token": "sankdsanlk",
'password': passcode
})
json_response = json.loads(response.content)
self.assertEqual(200, response.status_code)
self.assertEqual('mock_user@email.com', json_response.get("username"))
def test_request_token_email_not_exists(self):
email = 'mock_user1212@email.com'
passcode = 'pass12345'
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name',
"access_token": "sankdsanlk",
'password': passcode
})
json_response = json.loads(response.content)
self.assertEqual(404, response.status_code)
self.assertEqual(json_response['response'], "User not exist")
def test_request_token_not_active(self):
email = 'mock_user12@email.com'
password = 'pass12345'
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name12323',
"access_token": "sankdsanlk",
'password': password
})
json_response = json.loads(response.content)
self.assertEqual(400, response.status_code)
self.assertEqual(json_response['response'], "Please activate your account")
def test_user_wrong_password(self):
email = 'mock_user12@email.com'
password = 'pass123456'
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name',
"access_token": "sankdsanlk",
'password': password
})
json_response = json.loads(response.content)
self.assertEqual(400, response.status_code)
self.assertEqual(json_response['response'], "Wrong password")
@patch('oauth.views.json.loads')
def test_google_login_exist(self, mock_json_loads):
email = 'mock_user@email.com'
passcode = 'pass12345'
mock_json_loads.return_value = {"email": 'mock_user@email.com'}
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name',
"access_token": "sankdsanlk",
'password': passcode,
'google': True,
})
json_response = json.loads(response.content)
self.assertEqual(200, response.status_code)
self.assertEqual('mock_user@email.com', json_response.get("username"))
time.sleep(1)
@patch('oauth.views.json.loads')
def test_google_login_not_exist(self, mock_json_loads):
email = 'mock_user4545@email.com'
passcode = 'pass1234567'
mock_json_loads.return_value = {"email": 'mock_user4545@email.com'}
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name',
"access_token": "sankdsanlk",
'password': passcode,
'google': True,
})
json_response = json.loads(response.content)
self.assertEqual(200, response.status_code)
self.assertEqual('mock_user4545@email.com', json_response.get("username"))
time.sleep(1)
@patch('oauth.views.json.loads')
def test_google_login_error(self, mock_json_loads):
email = 'mock_user4545@email.com'
passcode = 'pass1234567'
mock_json_loads.return_value = {"error": 'error'}
response = Client().post('/api-token-auth/', {
'username': email,
'name': 'name',
"access_token": "sankdsanlk",
'password': passcode,
'google': True,
})
json_response = json.loads(response.content)
self.assertEqual(404, response.status_code)
self.assertTrue("message" in json_response)
time.sleep(1)
@patch('oauth.views.requests.get')
@patch('oauth.views.json.loads')
def test_validate_access_token_valid(self, mock_json_loads, mock_get):
mock_get.return_value.text = "DKSJNDKDSKN"
mock_json_loads.return_value = {"email": 'mock_user@email.com'}
result_flag, result_email = validate_google_token("DLSLDSMDSBAS^&**")
self.assertTrue(result_flag)
self.assertEqual('mock_user@email.com', result_email)
@patch('oauth.views.requests.get')
@patch('oauth.views.json.loads')
def test_validate_access_token_invalid(self, mock_json_loads, mock_get):
mock_get.return_value.text = "DKSJNDKDSKN"
mock_json_loads.return_value = {"error": 'error description'}
result_flag, result_email = validate_google_token("DLSLDSMDSBAS^&**")
json_response = json.loads(result_email.content)
self.assertTrue("message" in json_response)
self.assertEqual(404, result_email.status_code)
self.assertFalse(result_flag)
@patch('oauth.views.random.randint')
def test_create_phone_number_exist(self, mock_randint):
mock_randint.side_effect = [9, 1, 4, 5, 5, 4, 8, 0, 1, 1, 1, 1, 1, 1, 1, 1]
phone_number = _create_random_phone_number()
self.assertEqual('1x1x1x1x1x1x1x1', phone_number)
@patch('oauth.views.random.randint')
def test_create_phone_number_not_exist_already(self, mock_randint):
mock_randint.side_effect = [1, 1, 1, 1, 1, 1, 1, 1]
phone_number = _create_random_phone_number()
self.assertEqual('1x1x1x1x1x1x1x1', phone_number)
def test_create_google_user_exist(self):
user = _create_google_user('mock_user@email.com', 'name')
self.assertEqual('mock_user@email.com', user.username)
self.assertEqual('mock_user@email.com', user.email)
self.assertEqual('name', user.last_name)
@patch('oauth.views._create_random_phone_number')
def test_create_google_user_exist(self, mock_random_phone):
mock_random_phone.return_value = '1x1x1x1x1x1x1x1'
user = _create_google_user('mock_user3434@email.com', 'name')
self.assertEqual('mock_user3434@email.com', user.username)
self.assertEqual('mock_user3434@email.com', user.email)
self.assertEqual('name', user.last_name)
self.assertEqual('1x1x1x1x1x1x1x1', user.phone_number.phone_number)
import requests
import random
from urllib.parse import parse_qs, urlparse
from rest_framework.utils import json
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_simplejwt.tokens import RefreshToken
from rest_framework.permissions import IsAuthenticated
from rest_framework.authtoken.models import Token
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse, HttpResponse
from django.http import JsonResponse
from django.contrib.auth import authenticate
from django.contrib.auth.base_user import BaseUserManager
from django.contrib.auth.hashers import make_password
from django.contrib.auth.models import User
from pplbackend.settings import GOOGLE_OAUTH2_CLIENT_ID, GOOGLE_OAUTH2_CLIENT_SECRET
from django.conf import settings
from registrasi.models import BisaGoUser
@csrf_exempt
......@@ -27,30 +18,32 @@ def request_token(request):
password = request.POST["password"]
google = request.POST.get("google", False)
response = {}
status = 200
if google:
access_token = request.POST["access_token"]
name = request.POST["name"]
try:
user = User.objects.get(email=email)
result_code, result_email = validate_google_token(access_token)
if result_code:
user = User.objects.get(email=result_email)
email = result_email
else:
return result_email
except User.DoesNotExist:
user, status = _request_token_from_google(email, access_token, name)
user = _create_google_user(email, name)
else:
try:
user = authenticate(request, username=email, password=password)
if user is None:
User.objects.get(email=email)
except User.DoesNotExist:
response["response"] = "User not exist"
return JsonResponse(response, status=404)
if status != 200:
return response
if user is not None:
if user.is_active:
#print("user active")
token, create = Token.objects.get_or_create(user=user)
response = {}
response['username'] = user.username
response['token'] = token.key
response['token_type'] = "token"
response = {'username': user.username, 'token': token.key, 'token_type': "token"}
return JsonResponse(response, status=200)
else:
response["response"] = "Please activate your account"
......@@ -58,37 +51,43 @@ def request_token(request):
else:
response["response"] = "Wrong password"
return JsonResponse(response, status=400)
@csrf_exempt
def _request_token_from_google(email, access_token, name):
payload = {'access_token': access_token} # validate the token
req = requests.get('https://www.googleapis.com/oauth2/v2/userinfo', params=payload)
data = json.loads(req.text)
if 'error' in data:
content = {'message': 'wrong google token / this google token is already expired.'}
return None, JsonResponse(content, status=404)
user = User()
user.username = email
# provider random default password
user.password = make_password(BaseUserManager().make_random_password())
user.email = email
user.is_active = True
user.last_name = name
user.save()
random_generated_phone_number = 'x'.join([str(random.randint(0, 9)) for i in range(8)])
BisaGoUser.objects.create(user=user, phone_number=random_generated_phone_number)
return user, 200
def _create_google_user(email, name):
try:
return User.objects.get(username=email)
except User.DoesNotExist:
user = User()
user.username = email
# provider random default password
user.password = make_password(BaseUserManager().make_random_password())
user.email = email
user.is_active = True
user.last_name = name
user.save()
random_generated_phone_number = _create_random_phone_number()
BisaGoUser.objects.create(user=user, phone_number=random_generated_phone_number)
return user