diff --git a/data/logs/Development Plan.txt b/data/logs/Development Plan.txt deleted file mode 100644 index 88e9131f..00000000 --- a/data/logs/Development Plan.txt +++ /dev/null @@ -1,50 +0,0 @@ -================================================== -30/08/12: Τέλος εναρκτήριας φάσης. [ΟΛΟΚΛΗΡΩΘΗΚΕ] -================================================== -Θεωρητική επισκόπηση του έργου. Η φάση αυτή δεν έχει -πολύ σημασία λόγω του ότι πρόκειται για πτυχιακή -εργασία. - -Εργασίες που πρέπει να γίνουν: -* Vision Document -* Μελέτη τεχνολογιών που θα χρησιμοποιηθούν -* Πρόχειρη σχεδίαση υπηρεσιών του συστήματος -* Πρώιμα σχέδια αρχιτεκτονικής του κώδικα του - συστήματος - -================================================== -15/11/12: Τέλος φάσης εκπόνησης. -================================================== -Το σχέδιο για την εφαρμογή πρέπει να έχει εγκριθεί -όλες οι προετοιμασίες για την φάση της εκπόνησης να -έχουν εκπληρωθεί. - -Εργασίες που πρέπει να γίνουν: -* Έγγραφο Απαιτήσεων Συστήματος -* Επιλογή Εργαλείων Ανάπτυξης -* Δοκιμαστική Συγγραφή Τμηματικού Κώδικα (CodeIgniter, - και Google Calendar API) - -================================================== -30/12/12: Τέλος κατασκευαστικής φάσης. -================================================== -Η υλοποίηση της εφαρμογής πρέπει να ολοκληρωθεί σε -20 μέρες για να τελειώσει γρήγορα το project. - -Εργασίες που πρέπει να γίνουν: -* Υλοποίηση εφαρμογής -* Review Κώδικα -* Unit Tests -* Auto Build System - -================================================== -15/01/13: Τέλος μεταβατικής φάσης. -================================================== -Σε αυτήν την φάση η εφαρμογή βρίσκεται σε Beta στάδιο. -Δοκιμές για την σωστή εκτέλεση εργασιών, καλοποίηση της -εφαρμογής, documentation. - -Εργασίες που πρέπει να γίνουν: -* Δοκιμές εκτέλεσης εφαρμογής -* Καλοποίηση εφαρμογής -* Συγγραφή Code & User Documentation diff --git a/data/logs/Development Tools.txt b/data/logs/Development Tools.txt deleted file mode 100644 index dbba7d19..00000000 --- a/data/logs/Development Tools.txt +++ /dev/null @@ -1,19 +0,0 @@ -================================ -Windows -================================ -Development : Netbeans -UML Modeler : ArgoUML -Server Stack : Wamp Server -Design App : Gimp -Documentation : Open Office -Text Editor : Notepad++ - -================================ -Linux -================================ -Development : Netbeans -UML Modeler : ArgoUML -Server Stack : XAMPP For Linux -Design App : Gimp -Documentation : Open Office -Text Editor : gEdit diff --git a/data/logs/Project Tasks.ods b/data/logs/Project Tasks.ods deleted file mode 100644 index df6dfe75..00000000 Binary files a/data/logs/Project Tasks.ods and /dev/null differ diff --git a/data/logs/Risks Table.txt b/data/logs/Risks Table.txt deleted file mode 100644 index 9b13127f..00000000 --- a/data/logs/Risks Table.txt +++ /dev/null @@ -1,42 +0,0 @@ -======================================================= -Εβδομάδα #1 03/09/12 - 09/09/12 -======================================================= -01. Καθυστέρηση στην εκπλήρωση εργασιών. [ΛΥΘΗΚΕ] -02. Προβλήματα συμβατότητας μεταξύ των Windows & Linux. [ΛΥΘΗΚΕ] -03. Κακή επικοινωνία με τον καθηγητή. -04. Καθυστέρηση του έργου λόγω εργασίας σε άλλο project. -05. Καθυστέρηση του έργου λόγω εκμάθησης νέων εργαλείων. [ΛΥΘΗΚΕ] - -======================================================= -Εβδομάδα #2 10/09/12 - 16/09/12 -======================================================= -01. Κακή επικοινωνία με τον καθηγητή. -02. Καθυστέρηση του έργου λόγω εργασίας σε άλλο project. -03. Καθυστέρηση λόγω εξεταστικής. -04. Καθυστέρηση λόγω πρακτικής. -05. Καθυστέρηση λόγω εκμάθησης Google Calendar API. - -======================================================= -Εβδομάδα #3 17/09/12 - 23/09/12 -======================================================= -01. Κακή επικοινωνία με τον καθηγητή. -02. Καθυστέρηση του έργου λόγω εργασίας σε άλλο project. -03. Καθυστέρηση λόγω εξεταστικής. -04. Καθυστέρηση λόγω πρακτικής. -05. Καθυστέρηση λόγω εκμάθησης Google Calendar API. - -======================================================= -Εβδομάδα #4 24/09/12 - 30/09/12 -======================================================= -01. Κακή επικοινωνία με τον καθηγητή. [ΛΥΘΗΚΕ] -02. Καθυστέρηση του έργου λόγω εργασίας σε άλλο project. -03. Καθυστέρηση λόγω εξεταστικής. [ΛΥΘΗΚΕ] -04. Καθυστέρηση λόγω πρακτικής. -05. Καθυστέρηση λόγω εκμάθησης Google Calendar API. [ΛΥΘΗΚΕ] - -======================================================= -Εβδομάδα #5 01/10/12 - 07/10/12 -======================================================= -01. Καθυστέρηση του έργου λόγω εργασίας σε άλλο project. -02. Καθυστέρηση λόγω πρακτικής. -03. Καθυστέρηση του έργου λόγω εργασίας σε άλλο project. diff --git a/data/logs/Version Plan.ods b/data/logs/Version Plan.ods deleted file mode 100644 index 7530ad68..00000000 Binary files a/data/logs/Version Plan.ods and /dev/null differ diff --git a/doc/Unit Testing/unit-testing.pdf b/doc/Unit Testing/unit-testing.pdf new file mode 100644 index 00000000..53746f63 Binary files /dev/null and b/doc/Unit Testing/unit-testing.pdf differ diff --git a/doc/Unit Testing/unit-testing.tex b/doc/Unit Testing/unit-testing.tex new file mode 100644 index 00000000..063ca1e8 --- /dev/null +++ b/doc/Unit Testing/unit-testing.tex @@ -0,0 +1,131 @@ +%% ============================= +%% GENERAL SETTINGS +%% ============================= +\documentclass[12pt]{article} + +\usepackage [margin=2.5cm]{geometry} +\usepackage {graphics} +\usepackage {xltxtra} +\usepackage {xgreek} +\usepackage {color} +\usepackage {hyperref} +\hypersetup {colorlinks} + + +\setmainfont[Mapping=tex-text]{Tahoma} +\setlength{\parindent}{0cm} %% No paragraph indent + +\definecolor{darkred}{rgb}{0.5,0,0} +\definecolor{darkgreen}{rgb}{0,0.5,0} +\definecolor{darkblue}{rgb}{0,0,0.5} + +\hypersetup{ colorlinks, +linkcolor=darkblue, +filecolor=darkgreen, +urlcolor=darkblue, +citecolor=darkred } + +%% ============================= +%% DOCUMENT PROPERTIES +%% ============================= +\title{{\Huge {\bf Easy!Appointments}} \\[0.3cm] Unit Testing} +\author{Αλέξανδρος Τσελεγγίδης} +\date{Μάιος 2013} + +%% ============================= +%% DOCUMENT CONTENT +%% ============================= +\begin{document} +\maketitle +\thispagestyle{empty} %% Απομάκρυνση page number από την πρώτη σελίδα + +%% ΕΙΣΑΓΩΓΗ ΣΤΟ UNIT TESTING +\section {Εισαγωγή} +Σε κάθε τομέα παραγωγής προϊόντων είναι πολύ σημαντικό να παράγονται προϊόντα τα οποία να τηρούν πάντα τις προδιαγραφές τους και να μπορούν να αντεπεξέλθουν στις απαιτήσεις του καταναλωτικού κοινού. Η φήμη και η εμπιστοσύνη που προσδίδει μια εταιρεία είναι κομβικά χαρακτηριστικά για την βιωσιμότητας της. Κάθε επαγγελματίας είναι απαραίτητο να είναι σε θέση να εγγυηθεί για την ποιότητα του προϊόντος ή της υπηρεσίας που παρέχει ως αντάλλαγμα της αμοιβής του. +\\[0.3cm] +Ο τρόπος διασφάλισης της ποιότητας διαφέρει ανάλογα με την φύση του προϊόντος ή της υπηρεσίας και μπορεί να εκτελεστεί με διάφορους μεθόδους. Για παράδειγμα αν το προϊόν ήταν κάποιο τρόφιμο, η εταιρία θα έπρεπε να είναι σίγουρη ότι είναι σε άριστη κατάσταση πριν φτάσει στο τραπέζι του καταναλωτή, διότι αν δεν το έκανε αυτό θα υπήρχαν επιπλοκές στην υγεία των καταναλωτών. Αντίστοιχα μια εταιρία που παρέχει μια υπηρεσία πρέπει να διασφαλίσει και να ελέγξει την ποιότητα παροχής της υπηρεσίας με διάφορους τρόπους. Ένας από αυτούς θα ήταν να λαμβάνει τις παρατηρήσεις των καταναλωτών αφότου λάβουν την υπηρεσία ή να περνάει από εσωτερικές εξετάσεις και εκπαίδευση τους υπαλλήλους της έτσι ώστε να είναι σίγουρη ότι αυτοί θα μπορούν να παρέχουν σωστά και αξιόπιστα την υπηρεσία στους πελάτες. +\\[0.3cm] +Στην διαδικασία ανάπτυξης λογισμικού υπάρχουν αντίστοιχα διάφοροι τρόποι ελέγχου ότι το λογισμικό που αναπτύσσεται τηρεί τις προδιαγραφές του. Κάποιοι από αυτούς τους τρόπους είναι τα unit testing, fuzz testing, δημοσίευση δοκιμαστική έκδοσης (beta version) κ.α. Το πιο κοντινό εργαλείο ελέγχου στον προγραμματιστή είναι η διαδικασία unit testing, η οποία εφαρμόζεται αποκλειστικά σε αντικειμενοστραφή κώδικα. Παρακάτω θα γίνει μια ανάλυση αυτής της τεχνικής ελέγχου και θα αναφερθούν οι μέθοδοι και η διαδικασία ελέγχου πάνω στο Easy!Appointments. + +\section {Unit Testing} +Για την υλοποίηση unit tests πάνω στον κώδικα είναι απαραίτητο να τηρούνται δύο πράγματα: (1) η αντικειμενοστραφείς δομή και (2) η χρήση κάποιας βιβλιοθήκης ή εργαλείου το οποίο μπορεί να βοηθήσει στην οργάνωση και καλύτερη υλοποίηση των tests. +\\[0.3cm] +Με τον όρο unit testing εννοείται η δοκιμή μίας “λειτουργικής μονάδας” του λογισμικού που αναπτύσσεται. Η κάθε λειτουργική μονάδα απομονώνεται από τις υπόλοιπες και δοκιμάζεται ξεχωριστά σε διάφορες καταστάσης. Για αυτόν τον λόγο είναι απαραίτητο ο κώδικας να έχει αντικειμενοστραφής δομή. Η διαδικασία χωρίζεται στην συγγραφή πολλαπλών unit test, συναρτήσεων δηλαδή που δοκιμάζουν μια διαδικασία για συγκεκριμένες τιμές εισόδου. Σε κάθε περίπτωση στόχος είναι να υπάρχει ελεγχόμενη έξοδος έτσι ώστε να μπορέσει ο προγραμματιστής να είναι σίγουρος ότι το σύστημα θα λειτουργήσει σωστά σε οποιαδήποτε κατάσταση και αν βρίσκεται. Κατά την διαδικασία αυτήν μπορούν να βρεθούν πολύ εύκολα πολλά προβλήματα και ασυνέπειες στον κώδικα ενός συστήματος, τα οποία χρειάζεται να αντιμετωπιστούν. +\\[0.3cm] +Για να μπορέσουν να υλοποιηθούν αυτά τα test είναι απαραίτητο να χρησιμοποιηθεί κάποια βιβλιοθήκη ή εργαλείο, το οποίο θα κατέχει τις βασικές συναρτήσεις ελέγχου αποτελεσμάτων και επιπρόσθετα λειτουργίες για την παραγωγή αναφορών, οι οποίες περιέχουν τα αποτελέσματα των δοκιμών. Υπάρχουν πάρα πολλά εργαλεία που κάνουν αυτήν την δουλειά, το καθένα για μια συγκεκριμένη γλώσσα προγραμματισμού. Τα πιο διαδεδομένα εργαλεία είναι αυτά που ανήκουν στην οικογένεια xUnit (Junit, CppUnit, NUnit κ.α). +\\[0.3cm] +Τα εργαλεία αυτά μπορούν συνήθως κάλλιστα να συνεργαστούν μαζί με άλλα εργαλεία ανάπτυξης έτσι ώστε να είναι πολύ εύκολο για τον προγραμματιστή να συμπεριλάβει την διαδικασία unit testing στην υλοποίηση του κάθε συστήματος. + +\section {Easy!Appointments Testing} +Η συγγραφή των unit tests για το Easy!Appointmnets έγινε με την χρήση της ενσωματωμένης βιβλιοθήκης που παρέχει το CodeIginter. Η βιβλιοθήκη παρέχει τις βασικές λειτουργίες ελέγχου και παραγωγής αναφορών για τα tests του κώδικα. Προτιμήθηκε έναντι του phpunit λόγω της καλύτερης απόδοσης σε σχέση με το CodeIgniter Framework. +\\[0.3cm] +Η διαδικασία της δοκιμής του συστήματος ξεκίνησε από τα Models, τις λειτουργικές μονάδες που διαχειρίζονται την κίνηση προς και από την βάση δεδομένων. Είναι απαραίτητο για το σύστημα να κατέχει ακέραια δεδομένα μιας και όλη η εφαρμογή βασίζεται σε αυτά. Η κάθε μέθοδος του κάθε model δοκιμάστηκε ξεχωριστά από τις υπόλοιπες για 3-5 διαφορετικές περιπτώσεις κάθε φορά. Όσο αναπτύσσεται το σύστημα τόσο αυξάνονται και unit tests. +\\[0.3cm] +Για την σωστή δοκιμή του συστήματος απομονώθηκε το κάθε model και δοκιμάστηκε ανεξάρτητα από τα υπόλοιπα. Κάθε μέθοδος έχει κατά μέσω όρο 3-5 unit test, κάτι που μελλοντικά μπορεί να αυξηθεί όσο επεκτείνεται η εφαρμογή. + +\section {Παραδειγματα} +Στον παρακάτω κώδικα δοκιμάζεται η βασική ροή της περίπτωσης χρήσης “προσθήκη ραντεβού”. Σε αυτό το test case η είσοδος της μεθόδου add() είναι σωστή και έτσι περιμένουμε ότι και το αποτέλεσμα της διαδικασίας θα είναι επιτυχία. Στο τέλος αφαιρούμε την εγγραφή που προστέθηκε για να μην μείνουν κατάλοιπα στην βάση. Σε κάθε unit test χρησιμοποιείται μόνο μια μέθοδος του model. Έτσι το κάθε test δεν επιρρεάζεται από τυχόν προβλήματα σε άλλες μεθόδους του model. + +\begingroup +\fontsize{10pt}{12pt} +\begin{verbatim} +/** + * Test the appointment add method - insert new record. + */ +private function test_add_appointment_insert() { + // Add - insert new appointment record to the database. + $appointment_data = array( + 'start_datetime' => '2013-05-01 12:30:00', + 'end_datetime' => '2013-05-01 13:00:00', + 'notes' => 'Some notes right here...', + 'id_users_provider' => $this->provider_id, + 'id_users_customer' => $this->customer_id, + 'id_services' => $this->service_id + ); + $appointment_data['id'] = $this->CI->Appointments_Model + ->add($appointment_data); + $this->CI->unit->run($appointment_data['id'], 'is_int', + 'Test if add() appointment (insert operation) returned the db row id.'); + + // Check if the record is the one that was inserted. + $db_data = $this->CI->db->get_where('ea_appointments', + array('id' => $appointment_data['id']))->row_array(); + $this->CI->unit->run($appointment_data, $db_data, + 'Test if add() appointment (insert operation) has successfully inserted a record.'); + + // Delete inserted record. + $this->CI->db->delete('ea_appointments', + array('id' => $appointment_data['id'])); +} +\end{verbatim} +\endgroup +Στο παρακάτω unit test δοκιμάζεται η μέθοδος get\_value() η οποία επιστρέφει την τιμή ενός πεδίου από την βάση. Στο συγκεκριμένο test case δίνεται ως παράμετρος ένα id εγγραφής, το οποίο δεν υπάρχει στην βάση. Η αναμενόμενη συμπεριφορά από το model είναι να εμφανιστεί ένα exception το οποίο να ειδοποιεί ότι η εγγραφή με το συγκεκριμένο id δεν βρέθηκε στην βάση. + +\begingroup +\fontsize{10pt}{12pt} +\begin{verbatim} +/** + * Test the get field value method with a record id that + * doesn't exist in the db. + * + * A database exception is expected. + */ +private function test_get_value_record_does_not_exist() { + $random_record_id = 843521368768; + + $has_thrown_exception = FALSE; + + try { + $this->CI->Appointments_Model->get_value('start_datetime', $random_record_id); + } catch (InvalidArgumentException $db_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that does not exist.'); +} +\end{verbatim} +\endgroup + +Κάποια unit test δοκιμάζουν τις μεθόδους για σωστές τιμές και αναμένουν την επιτυχή ολοκλήρωση των διαδικασιών τους. Τα περισσότερα όμως tests σκοπό έχουν να δουν την συμπεριφορά του συστήματος για τιμές οι οποίες δεν είναι φυσιολογικές. Με αυτόν τον τρόπο μπορούν να προβλεφθούν πολλά bug και άλλα προβλήματα στον κώδικα και η εφαρμογή να είναι περισσότερο αξιόπιστη και δυνατή απέναντι σε σφάλματα. + +\end{document} \ No newline at end of file diff --git a/src/application/libraries/Unit_tests/drivers/Unit_tests_appointments_model.php b/src/application/libraries/Unit_tests/drivers/Unit_tests_appointments_model.php index 8a77abdc..84aa6aff 100644 --- a/src/application/libraries/Unit_tests/drivers/Unit_tests_appointments_model.php +++ b/src/application/libraries/Unit_tests/drivers/Unit_tests_appointments_model.php @@ -161,7 +161,7 @@ class Unit_tests_appointments_model extends CI_Driver { } private function test_exists_record_does_not_exist() { - // Create random appointmnet data that doesn't exist in the database. + // Create random appointment data that doesn't exist in the database. $appointment_data = array( 'start_datetime' => '2013-05-01 08:33:45', 'end_datetime' => '2013-05-02 13:13:13', @@ -175,7 +175,7 @@ class Unit_tests_appointments_model extends CI_Driver { } private function test_exists_with_wrong_data() { - // Create random appointmnet data that doesn't exist in the database. + // Create random appointment data that doesn't exist in the database. $appointment_data = array( 'start_datetime' => '2WRONG013-05-01 0WRONG8:33:45', 'end_datetime' => '2013-0WRONG5-02 13:13:WRONG13', @@ -190,10 +190,10 @@ class Unit_tests_appointments_model extends CI_Driver { /** * Test the find record id method with a record that already - * exists in the databse. + * exists in the database. */ private function test_find_record_id() { - // Create a new appointmnet record. + // Create a new appointment record. $appointment_data = array( 'start_datetime' => '2013-05-01 12:30:00', 'end_datetime' => '2013-05-01 13:00:00', @@ -262,7 +262,7 @@ class Unit_tests_appointments_model extends CI_Driver { 'id_services' => 'WRONG' ); - // Try to find the appointmet's record id. A database + // Try to find the appointment's record id. A database // exception should be raised. $has_thrown_exception = FALSE; @@ -280,7 +280,7 @@ class Unit_tests_appointments_model extends CI_Driver { * Test the normal flow of deleting an appointment record. */ private function test_delete() { - // Create a new appointmnet record. + // Create a new appointment record. $appointment_data = array( 'start_datetime' => '2013-05-01 12:30:00', 'end_datetime' => '2013-05-01 13:00:00', @@ -395,7 +395,7 @@ class Unit_tests_appointments_model extends CI_Driver { } $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_batch() with wrong where clause.', - 'A database excpetion is expected to be thrown.'); + 'A database exception is expected to be thrown.'); } /** diff --git a/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php b/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php new file mode 100644 index 00000000..4b7095de --- /dev/null +++ b/src/application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php @@ -0,0 +1,199 @@ +CI =& get_instance(); + $this->CI->load->library('Unit_test'); + $this->CI->load->model('Providers_Model'); + + $this->provider_role_id = $this->CI->db->get_where('ea_roles', array('slug' => DB_SLUG_PROVIDER))->row()->id; + } + + /** + * Run all the available tests + */ + public function run_all() { + // All the methods whose names start with "test" are going to be + // executed. If you want a method to not be executed remove the + // "test" keyword from the beginning. + $class_methods = get_class_methods('Unit_tests_providers_model'); + foreach ($class_methods as $method_name) { + if (substr($method_name, 0, 5) === 'test_') { + call_user_func(array($this, $method_name)); + } + } + } + + ///////////////////////////////////////////////////////////////////////// + // UNIT TESTS + ///////////////////////////////////////////////////////////////////////// + + // TEST GET ROW METHOD --------------------------------------------- + private function test_get_row() { + // Insert a new customer record. + $provider_data = array( + 'last_name' => 'Doe', + 'first_name' => 'John', + 'email' => 'alextselegidis@gmail.com', + 'phone_number' => '0123456789', + 'address' => 'Abbey Road 18', + 'city' => 'London', + 'zip_code' => '12345', + 'id_roles' => $this->provider_role_id + ); + $this->CI->db->insert('ea_users', $provider_data); + $provider_data['id'] = intval($this->CI->db->insert_id()); + + // Get the new customer record from db. + $no_model_data = $this->CI->db->get_where('ea_users', array('id' => $provider_data['id']))->row_array(); + $model_data = $this->CI->Providers_Model->get_row($provider_data['id']); + + // Check that the row is the correct one. + $this->CI->unit->run($no_model_data, $model_data, 'Test get_row() method'); + + // Delete inserted customer record. + $this->CI->db->delete('ea_users', array('id' => $provider_data['id'])); + } + + private function test_get_row_that_does_not_exist() { + $random_record_id = 486868412; + $row_data = $this->CI->Providers_Model->get_row($random_record_id); + $this->CI->unit->run($row_data, NULL, 'Test get_row() with record id that does ' + . 'not exist in the database.'); + } + + private function test_get_row_with_invalid_argument() { + $invalid_id = 'THIS IS NOT AN INTEGER'; + + $has_thrown_exception = FALSE; + try { + $this->CI->Providers_Model->get_row($invalid_id); + } catch (InvalidArgumentException $ia_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_row() with wrong argument.'); + } + + // TEST GET VALUE METHOD --------------------------------------------- + private function test_get_value() { + // Insert new customer record. + $provider_data = array( + 'last_name' => 'Doe', + 'first_name' => 'John', + 'email' => 'alextselegidis@gmail.com', + 'phone_number' => '0123456789', + 'address' => 'Abbey Road 18', + 'city' => 'London', + 'zip_code' => '12345', + 'id_roles' => $this->provider_role_id + ); + $this->CI->db->insert('ea_users', $provider_data); + $provider_data['id'] = intval($this->CI->db->insert_id()); + + // Get a specific value from the database. + $model_value = $this->CI->Providers_Model->get_value('email', $provider_data['id']); + + // Check if the value was correctly fetched from the database. + $this->CI->unit->run($model_value, $provider_data['email'], 'Test get_value() method.'); + + // Delete inserted appointment record. + $this->CI->db->delete('ea_users', array('id' => $provider_data['id'])); + } + + private function test_get_value_record_does_not_exist() { + $random_record_id = 843521368768; + + $has_thrown_exception = FALSE; + + try { + $this->CI->Providers_Model->get_value('email', $random_record_id); + } catch (InvalidArgumentException $db_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that does not exist.'); + } + + private function test_get_value_field_does_not_exist() { + // Insert new customer record. + $provider_data = array( + 'last_name' => 'Doe', + 'first_name' => 'John', + 'email' => 'alextselegidis@gmail.com', + 'phone_number' => '0123456789', + 'address' => 'Abbey Road 18', + 'city' => 'London', + 'zip_code' => '12345', + 'id_roles' => $this->provider_role_id + ); + $this->CI->db->insert('ea_users', $provider_data); + $provider_data['id'] = intval($this->CI->db->insert_id()); + + // Try to get record value with wrong field name. + $wrong_field_name = 'THIS IS WRONG'; + $has_thrown_exception = FALSE; + + try { + $this->CI->Providers_Model->get_value($wrong_field_name, $provider_data['id']); + } catch (InvalidArgumentException $db_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that does not exist.'); + + // Delete inserted appointment record. + $this->CI->db->delete('ea_users', array('id' => $provider_data['id'])); + } + + // TEST GET BATCH METHOD --------------------------------------------- + private function test_get_batch() { + // Get all the customer rows without using the model. + $db_data = $this->CI->db->get_where('ea_users', array('id_roles' => $this->provider_role_id))->result_array(); + // Get all the customer rows by using the model. + $model_data = $this->CI->Providers_Model->get_batch(); + // Check that the two arrays are the same. + $this->CI->unit->run($db_data, $model_data, 'Test get_batch() method.'); + } + + private function test_get_batch_with_where_clause() { + // Insert new customer record. + $provider_data = array( + 'last_name' => 'Doe', + 'first_name' => 'John', + 'email' => 'alextselegidis@gmail.com', + 'phone_number' => '0123456789', + 'address' => 'Abbey Road 18', + 'city' => 'London', + 'zip_code' => '12345', + 'id_roles' => $this->provider_role_id + ); + $this->CI->db->insert('ea_users', $provider_data); + $provider_data['id'] = intval($this->CI->db->insert_id()); + + // Get data without using the model. + $no_model_data = $this->CI->db->get_where('ea_users', array('id' => $provider_data['id']))->result_array(); + + // Get data by using the model. + $model_data = $this->CI->Providers_Model->get_batch(array('id' => $provider_data['id'])); + + // Check that the data arrays are the same. + $this->CI->unit->run($no_model_data, $model_data, 'Test get_batch() with where clause.'); + + // Delete inserted record from database. + $this->CI->db->delete('ea_users', array('id' => $provider_data['id'])); + } + + private function unabled_test_get_batch_with_invalid_where_clause() { + // CodeIgniter auto raises an exception if the where section is invalid. + } +} + +/* End of file Unit_tests_providers_model.php */ +/* Location: ./application/libraries/Unit_tests/drivers/Unit_tests_providers_model.php */ diff --git a/src/application/libraries/Unit_tests/drivers/Unit_tests_services_model.php b/src/application/libraries/Unit_tests/drivers/Unit_tests_services_model.php new file mode 100644 index 00000000..73db43e6 --- /dev/null +++ b/src/application/libraries/Unit_tests/drivers/Unit_tests_services_model.php @@ -0,0 +1,186 @@ +CI =& get_instance(); + $this->CI->load->library('Unit_test'); + $this->CI->load->model('Services_Model'); + } + + /** + * Run all the available tests + */ + public function run_all() { + // All the methods whose names start with "test" are going to be + // executed. If you want a method to not be executed remove the + // "test" keyword from the beginning. + $class_methods = get_class_methods('Unit_tests_services_model'); + foreach ($class_methods as $method_name) { + if (substr($method_name, 0, 5) === 'test_') { + call_user_func(array($this, $method_name)); + } + } + } + + ///////////////////////////////////////////////////////////////////////// + // UNIT TESTS + ///////////////////////////////////////////////////////////////////////// + + // TEST GET BATCH METHOD ----------------------------------------- + private function test_get_batch() { + // Get all the service rows without using the model. + $db_data = $this->CI->db->get('ea_services')->result_array(); + // Get all the service rows by using the model. + $model_data = $this->CI->Services_Model->get_batch(); + // Check that the two arrays are the same. + $this->CI->unit->run($db_data, $model_data, 'Test get_batch() method.'); + } + + private function test_get_batch_with_where_clause() { + // Insert new service record. + $service_data = array( + 'name' => 'General Examination', + 'duration' => 30, + 'price' => 50.00, + 'currency' => 'euro', + 'description' => 'This is some service description.' + ); + + $this->CI->db->insert('ea_services', $service_data); + $service_data['id'] = intval($this->CI->db->insert_id()); + + // Get data without using the model. + $no_model_data = $this->CI->db->get_where('ea_services', array('id' => $service_data['id']))->result_array(); + + // Get data by using the model. + $model_data = $this->CI->Services_Model->get_batch(array('id' => $service_data['id'])); + + // Check that the data arrays are the same. + $this->CI->unit->run($no_model_data, $model_data, 'Test get_batch() with where clause.'); + + // Delete inserted record from database. + $this->CI->db->delete('ea_services', array('id' => $service_data['id'])); + } + + private function unabled_test_get_batch_with_invalid_where_clause() { + // CodeIgniter auto raises an exception if the where section is invalid. + } + + // TEST GET ROW METHOD ----------------------------------------- + private function test_get_row() { + // Insert a new service record. + $service_data = array( + 'name' => 'General Examination', + 'duration' => 30, + 'price' => 50.00, + 'currency' => 'euro', + 'description' => 'This is some service description.' + ); + + $this->CI->db->insert('ea_services', $service_data); + $service_data['id'] = intval($this->CI->db->insert_id()); + + // Get the new service record from db. + $no_model_data = $this->CI->db->get_where('ea_services', array('id' => $service_data['id']))->row_array(); + $model_data = $this->CI->Services_Model->get_row($service_data['id']); + + // Check that the row is the correct one. + $this->CI->unit->run($no_model_data, $model_data, 'Test get_row() method'); + + // Delete inserted service record. + $this->CI->db->delete('ea_services', array('id' => $service_data['id'])); + } + + private function test_get_row_that_does_not_exist() { + $random_record_id = 486868412; + $row_data = $this->CI->Services_Model->get_row($random_record_id); + $this->CI->unit->run($row_data, NULL, 'Test get_row() with record id that does ' + . 'not exist in the database.'); + } + + private function test_get_row_with_invalid_argument() { + $invalid_id = 'THIS IS NOT AN INTEGER'; + + $has_thrown_exception = FALSE; + try { + $this->CI->Services_Model->get_row($invalid_id); + } catch (InvalidArgumentException $ia_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_row() with wrong argument.'); + } + + // TEST GET VALUE METHOD ----------------------------------------- + private function test_get_value() { + // Insert new service record. + $service_data = array( + 'name' => 'General Examination', + 'duration' => 30, + 'price' => 50.00, + 'currency' => 'euro', + 'description' => 'This is some service description.' + ); + $this->CI->db->insert('ea_services', $service_data); + $service_data['id'] = intval($this->CI->db->insert_id()); + + // Get a specific value from the database. + $model_value = $this->CI->Services_Model->get_value('name', $service_data['id']); + + // Check if the value was correctly fetched from the database. + $this->CI->unit->run($model_value, $service_data['name'], 'Test get_value() method.'); + + // Delete inserted appointment record. + $this->CI->db->delete('ea_services', array('id' => $service_data['id'])); + } + + private function test_get_value_record_does_not_exist() { + $random_record_id = 843521368768; + + $has_thrown_exception = FALSE; + + try { + $this->CI->Services_Model->get_value('name', $random_record_id); + } catch (InvalidArgumentException $db_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that does not exist.'); + } + + private function test_get_value_field_does_not_exist() { + // Insert new service record. + $service_data = array( + 'name' => 'General Examination', + 'duration' => 30, + 'price' => 50.00, + 'currency' => 'euro', + 'description' => 'This is some service description.' + ); + $this->CI->db->insert('ea_services', $service_data); + $service_data['id'] = intval($this->CI->db->insert_id()); + + // Try to get record value with wrong field name. + $wrong_field_name = 'THIS IS WRONG'; + $has_thrown_exception = FALSE; + + try { + $this->CI->Services_Model->get_value($wrong_field_name, $service_data['id']); + } catch (InvalidArgumentException $db_exc) { + $has_thrown_exception = TRUE; + } + + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_value() with record id that does not exist.'); + + // Delete inserted service record. + $this->CI->db->delete('ea_services', array('id' => $service_data['id'])); + } +} + +/* End of file Unit_tests_services_model.php */ +/* Location: ./application/libraries/Unit_tests/drivers/Unit_tests_services_model.php */ diff --git a/src/application/libraries/Unit_tests/drivers/Unit_tests_settings_model.php b/src/application/libraries/Unit_tests/drivers/Unit_tests_settings_model.php new file mode 100644 index 00000000..acde4d98 --- /dev/null +++ b/src/application/libraries/Unit_tests/drivers/Unit_tests_settings_model.php @@ -0,0 +1,167 @@ +CI =& get_instance(); + $this->CI->load->library('Unit_test'); + $this->CI->load->model('Settings_Model'); + } + + /** + * Run all the available tests + */ + public function run_all() { + // All the methods whose names start with "test" are going to be + // executed. If you want a method to not be executed remove the + // "test" keyword from the beginning. + $class_methods = get_class_methods('Unit_tests_settings_model'); + foreach ($class_methods as $method_name) { + if (substr($method_name, 0, 5) === 'test_') { + call_user_func(array($this, $method_name)); + } + } + } + + ///////////////////////////////////////////////////////////////////////// + // UNIT TESTS + ///////////////////////////////////////////////////////////////////////// + + // TEST GET SETTING METHOD + private function test_get_setting() { + // Insert new setting to database. + $setting_data = array( + 'name' => 'test_name', + 'value' => 'test_value' + ); + $this->CI->db->insert('ea_settings', $setting_data); + $setting_data['id'] = intval($this->CI->db->insert_id()); + + // Try to get the setting value by using the model. + $model_value = $this->CI->Settings_Model->get_setting('test_name'); + $this->CI->unit->run($model_value, $setting_data['value'], 'Test get_setting() method.'); + + // Delete inserted setting. + $this->CI->db->delete('ea_settings', array('id' => $setting_data['id'])); + } + + private function test_get_setting_invalid_argument() { + $invalid_argument = 564658765; + $has_thrown_exception = FALSE; + try { + $this->CI->Settings_Model->get_setting($invalid_argument); + } catch (InvalidArgumentException $ia_exc) { + $has_thrown_exception = TRUE; + } + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_setting() with invalid method argument.'); + } + + private function test_get_setting_that_does_not_exist() { + $setting_name = 'THIS NAME DOES NOT EXIST IN DB'; + $has_thrown_exception = FALSE; + try { + $this->CI->Settings_Model->get_setting($setting_name); + } catch (InvalidArgumentException $ia_exc) { + $has_thrown_exception = TRUE; + } + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test get_setting() with a name that does not exist in database.'); + } + + // TEST SET SETTING METHOD + private function test_set_setting_insert() { + $setting_data = array( + 'name' => 'test_setting', + 'value' => 'test_value' + ); + + // Insert setting by using the model. + $setting_data['id'] = $this->CI->Settings_Model->set_setting($setting_data['name'], $setting_data['value']); + $this->CI->unit->run($setting_data['id'], 'is_int', 'Test that set_setting() method (insert operation) has returned the setting database id.'); + + // Check that the setting has been successfully inserted. + $db_data = $this->CI->db->get_where('ea_settings', array('id' => $setting_data['id']))->row_array(); + $this->CI->unit->run($setting_data, $db_data, 'Test set_setting() method has successfully inserted the setting into the database.'); + + // Delete inserted setting. + $this->CI->db->delete('ea_settings', array('id' => $setting_data['id'])); + } + + private function test_set_setting_update() { + // Insert new setting into database. + $setting_data = array( + 'name' => 'test_name', + 'value' => 'test_value' + ); + $this->CI->db->insert('ea_settings', $setting_data); + $setting_data['id'] = intval($this->CI->db->insert_id()); + + // Update the inserted setting. + $new_setting_value = 'new_test_value'; + $set_setting_result = $this->CI->Settings_Model->set_setting($setting_data['name'], $new_setting_value); + $this->CI->unit->run($set_setting_result, 'is_int', 'Test that set_setting() method (update operation) has returned the setting database id.'); + + // Check if the update operation was completed successfully. + $db_setting_value = $this->CI->db->get_where('ea_settings', array('id' => $setting_data['id']))->row()->value; + $this->CI->unit->run($db_setting_value, $new_setting_value, 'Test set_setting() method has successfully updated a setting value.'); + + // Delete inserted record. + $this->CI->db->delete('ea_settings', array('id' => $setting_data['id'])); + } + + private function test_set_setting_invalid_setting_name() { + $invalid_setting_name = 1219087912; + $has_thrown_exception = FALSE; + try { + $this->CI->Settings_Model->set_setting($invalid_setting_name, 'test_value'); + } catch (InvalidArgumentException $id_exc) { + $has_thrown_exception = TRUE; + } + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test set_setting() method with invalid argument.'); + } + + // TEST REMOVE SETTING METHOD + private function test_remove_setting() { + // Insert new setting + $setting_data = array( + 'name' => 'test_name', + 'value' => 'test_value' + ); + $this->CI->db->insert('ea_settings', $setting_data); + $setting_data['id'] = intval($this->CI->db->insert_id()); + + // Remove setting + $remove_setting_result = $this->CI->Settings_Model->remove_setting($setting_data['name']); + $this->CI->unit->run($remove_setting_result, TRUE, 'Test remove_setting() return value.'); + + // Check if setting is removed + $num_rows = $this->CI->db->get_where('ea_settings', array('id' => $setting_data['id']))->num_rows(); + $this->CI->unit->run($num_rows, 0, 'Test if remove_setting() method has successfully removed the setting from the database.'); + if ($num_rows > 0) { + $this->CI->db->delete('ea_settings', array('id' => $setting_data['id'])); + } + } + + private function test_remove_setting_record_does_not_exist() { + $random_setting_name = 'THIS IS TOTALLY RANDOM'; + $remove_setting_result = $this->CI->Settings_Model->remove_setting($random_setting_name); + $this->CI->unit->run($remove_setting_result, FALSE, 'Test remove_setting() with record that does not exist.'); + } + + private function test_remove_setting_invalid_setting_name() { + $invalid_setting_name = 12092130968; + $has_thrown_exception = FALSE; + try { + $this->CI->Settings_Model->remove_setting($invalid_setting_name); + } catch (InvalidArgumentException $ia_exc) { + $has_thrown_exception = TRUE; + } + $this->CI->unit->run($has_thrown_exception, TRUE, 'Test remove_setting() with invalid setting name.'); + } +} + +/* End of file Unit_tests_settings_model.php */ +/* Location: ./application/libraries/Unit_tests/drivers/Unit_tests_settings_model.php */ \ No newline at end of file