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

Test ci #2

Merged
merged 15 commits into from
May 8, 2024
Merged
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
40 changes: 40 additions & 0 deletions .github/workflows/run-apps-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Run Apps Tests

on:
push:
branches:
- main
jobs:
test:
runs-on: ubuntu-latest

services:
sqlite:
image: python:3
env:
SQLITE_DB: test_db.sqlite3
ports:
- 5432:5432

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.11

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Prepare SQLite database
run: |
python manage.py migrate

- name: Run tests
run: |
python manage.py test

Empty file added apps/__init__.py
Empty file.
2 changes: 0 additions & 2 deletions apps/fsm/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
from fsm.tests.invitation_tests import InvitationTest
from fsm.tests import registration_tests
File renamed without changes.
3 changes: 0 additions & 3 deletions apps/report/tests.py

This file was deleted.

Empty file added apps/report/tests/__init__.py
Empty file.
65 changes: 65 additions & 0 deletions apps/report/tests/test_health_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
from django.test import TestCase, Client, override_settings
from django.urls import reverse
from django.apps import apps
import csv


class ViewTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.client = Client()

def setUp(self):
pass

def tearDown(self):
pass


class ExportViewTest(ViewTestCase):
def test_export_view(self):
with override_settings(ROOT_URLCONF='report.urls'):
url = reverse('export_json')
response = self.client.get(url)

self.assertEqual(response.status_code, 200)
self.assertEqual(response['Content-Type'], 'application/json')

self.assertTrue(response.content)

self.assertTrue('Content-Disposition' in response)

self.assertTrue('attachment' in response['Content-Disposition'])
self.assertTrue(
'exported_data.json' in response['Content-Disposition'])


class ExportCSVViewTest(ViewTestCase):
def test_export_csv_view(self):
with override_settings(ROOT_URLCONF='report.urls'):

url = reverse('export_csv')
response = self.client.get(url)
self.assertEqual(response.status_code, 200)

self.assertEqual(response['Content-Type'], 'text/csv')

self.assertTrue(response.content)

self.assertTrue('Content-Disposition' in response)

self.assertTrue('attachment' in response['Content-Disposition'])

self.assertTrue(
'exported_data.csv' in response['Content-Disposition'])
csv_data = response.content.decode('utf-8').splitlines()
csv_reader = csv.reader(csv_data)
header_row = next(csv_reader)
expected_header = [f"{model.__name__}_{field.name}" for model in apps.get_models(
) for field in model._meta.fields]
self.assertEqual(header_row, expected_header)
num_rows = len(list(csv_reader))
expected_num_rows = sum(model.objects.count()
for model in apps.get_models())
self.assertEqual(num_rows, expected_num_rows)
3 changes: 0 additions & 3 deletions apps/roadmap/tests.py

This file was deleted.

Empty file added apps/roadmap/tests/__init__.py
Empty file.
39 changes: 39 additions & 0 deletions apps/roadmap/tests/test_health_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from django.test import TestCase
from rest_framework.test import APIRequestFactory
from rest_framework import status
from unittest.mock import patch, MagicMock
from apps.roadmap.views import get_player_taken_path, get_fsm_roadmap


class TestRoadmapViewsHealthCheck(TestCase):
def setUp(self):
pass

def test_get_player_taken_path(self):
with patch('apps.roadmap.views.Player.get_player') as mocked_get_player:
player_instance = MagicMock()
player_instance.current_state.fsm = MagicMock()
mocked_get_player.return_value = player_instance

# Mocking _get_previous_taken_state
with patch('apps.roadmap.views._get_previous_taken_state') as mocked_prev_taken_state:
mocked_prev_taken_state.return_value = None

data = {'player_id': 1}
request = APIRequestFactory().post('get_player_taken_path/', data)
response = get_player_taken_path(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)

def test_get_fsm_roadmap(self):
with patch('apps.roadmap.views.FSM.get_fsm') as mocked_get_fsm, \
patch('apps.roadmap.views._get_fsm_edges') as mocked_get_fsm_edges:
fsm_instance = MagicMock()
fsm_instance.first_state.name = "First State"
mocked_get_fsm.return_value = fsm_instance
mocked_get_fsm_edges.return_value = [
MagicMock(tail=MagicMock(), head=MagicMock())]

data = {'fsm_id': 1}
request = APIRequestFactory().post('get_fsm_roadmap/', data)
response = get_fsm_roadmap(request)
self.assertEqual(response.status_code, status.HTTP_200_OK)
47 changes: 47 additions & 0 deletions apps/roadmap/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@

from apps.fsm.views.fsm_view import _get_fsm_edges

from apps.roadmap.models import Link
from apps.fsm.models import FSM, Player, PlayerHistory, State


def _get_fsm_links(fsm_id: int):
fsm = FSM.get_fsm(fsm_id)
edges = _get_fsm_edges(fsm)
links = [Link.get_link_from_states(
edge.tail, edge.head) for edge in edges]
return links


def _get_player_taken_path(player_id: int):
player = Player.get_player(player_id)
player_current_state: State = player.current_state
fsm = player_current_state.fsm
histories: list[PlayerHistory] = player.histories.all()
taken_path: list[Link] = []

# 100 is consumed as maximum length in a fsm graph
for i in range(100):
previous_state = _get_previous_taken_state(
player_current_state, histories)
# if the entered_by_edge is deleted, it isn't possible to reach to previous state
if not previous_state:
break
taken_path.append(Link.get_link_from_states(
previous_state, player_current_state))
player_current_state = previous_state

taken_path.reverse()
return taken_path


def _get_previous_taken_state(player_current_state: State, histories: list[PlayerHistory]):
for history in histories:
if history.reverse_enter:
continue
# if the entered_by_edge is deleted:
if not history.entered_by_edge:
continue
if history.entered_by_edge.head == player_current_state:
return history.entered_by_edge.tail
return None
47 changes: 2 additions & 45 deletions apps/roadmap/views.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import json
from rest_framework import status
from rest_framework.response import Response

from rest_framework.response import Response
from rest_framework.decorators import api_view
from apps.fsm.views.fsm_view import _get_fsm_edges

from apps.roadmap.models import Link
from apps.fsm.models import FSM, Player, PlayerHistory, State
from apps.fsm.models import FSM
from apps.roadmap.serializers import LinkSerializer
from apps.roadmap.utils import _get_fsm_links, _get_player_taken_path


@api_view(["POST"])
Expand All @@ -24,45 +23,3 @@ def get_fsm_roadmap(request):
fsm = FSM.get_fsm(fsm_id)
fsm_links = _get_fsm_links(fsm_id)
return Response(data={'first_state_name': fsm.first_state.name, 'links': LinkSerializer(fsm_links, many=True).data}, status=status.HTTP_200_OK)


def _get_fsm_links(fsm_id: int):
fsm = FSM.get_fsm(fsm_id)
edges = _get_fsm_edges(fsm)
links = [Link.get_link_from_states(
edge.tail, edge.head) for edge in edges]
return links


def _get_player_taken_path(player_id: int):
player = Player.get_player(player_id)
player_current_state: State = player.current_state
fsm = player_current_state.fsm
histories: list[PlayerHistory] = player.histories.all()
taken_path: list[Link] = []

# 100 is consumed as maximum length in a fsm graph
for i in range(100):
previous_state = _get_previous_taken_state(
player_current_state, histories)
# if the entered_by_edge is deleted, it isn't possible to reach to previous state
if not previous_state:
break
taken_path.append(Link.get_link_from_states(
previous_state, player_current_state))
player_current_state = previous_state

taken_path.reverse()
return taken_path


def _get_previous_taken_state(player_current_state: State, histories: list[PlayerHistory]):
for history in histories:
if history.reverse_enter:
continue
# if the entered_by_edge is deleted:
if not history.entered_by_edge:
continue
if history.entered_by_edge.head == player_current_state:
return history.entered_by_edge.tail
return None