CAW1 2015 Projet de Mickaël Bourgier et Marcelin Lazzarotto

De Ensiwiki
Aller à : navigation, rechercher
Project schedule.png
Titre du projet Alternet
Cadre Projet web

Équipe Mickaël Bourgier Marcelin Lazzarotto
Encadrants Sebastien Viardot


Sommaire

 Présentation Générale

Contexte

Le cours de Construction d'Application Web des apprentis de deuxième année à l'Ensimag aboutit à un projet de développement d'un site en équipe. Le sujet est laissé libre, tandis que certaines contraintes sommaires doivent être suivies. Cette page détaillera ces deux derniers points.

Principe

Laissez-moi vous présenter Alice, Bob et Charlie.

Alice est une très bonne cuisinière, elle adore préparer de bons petits plats pour sa famille et ses amis. Bob quant à lui, possède un potager dans son jardin qui produit énormément de légumes (presque trop même, il en donne souvent à sa famille ou ses amis). Charlie habite vers chez Bob et le croise tous les matin à l'arrêt de bus qui est sur sa route lorsqu'il part en voiture.

Grâce à Alternet, Charlie va commencer par proposer du covoiturage pour aller de chez lui à son travail, ce qui va intéresser Bob qui commençait à en avoir marre de prendre le bus. En discutant dans la voiture, Charlie donne l'idée à Bob de mettre en vente ses légumes sur la plateforme.

Alice qui était justement en train de chercher comment manger mieux et plus responsable avec des aliments de qualité et locaux, découvre l'annonce de Bob et lui achète des légumes. Voyant son porte monnaie virtuel descendre rapidement, Alice se dit que Bob ne lui ferait plus confiance pour continuer de lui donner des légumes sans contrepartie, c'est pourquoi elle décida de vendre quelques plats qu'elle aime tant concocter.

C'est en voyant cette annonce que Charles trouva enfin un moyen simple pour manger le midi, qu'il préféra aux restos ou sandwiches dont il avait l'habitude.

Et la boucle est bouclée : chacune de ces trois personnes proposent des services et chacune en consomme, à chaque transaction leur porte monnaie se voient créditer ou débiter le montant du service proposé ou consommé. C'est un petit exemple mais qui permet de s'imaginer comment pourrait fonctionner Alternet avec beaucoup plus de personnes.

Pour résumer, Alternet est une application de vente de service. C'est un réseau qui offre des fonctionnalités similaire à http://www.leboncoin.fr/, par exemple. Alternet se veut communautaire et facile d'accès.

L'idée derrière l'application est aussi d'utiliser un modèle économique différent de celui de la vie courante.

Modèle Économique

Nous souhaitions, à la création de l'application, que les gens utilisent une monnaie interne au programme. Cette monnaie est initialisée pour chaque inscrit à 0 et cette somme varie en fonction de son offre et/ou de sa demande de services. La somme totale de tous les portes monnaies reste toujours égale à 0, c'est pourquoi un utilisateur peut très bien avoir un solde négatif.

Alternet est donc basé sur l'échange. Les utilisateurs doivent proposer des services pour pouvoir gagner la monnaie qu'ils dépenseront pour acheter des services et ainsi de suite. Cela crée ainsi un jeu à somme nulle, ou chaque personne doit proposer autant qu'il doit recevoir.

 Cahier des Charges

Diagramme de classes

876145f1.png

Quelques informations supplémentaires :

La classe Request correspond à la demande d'un utilisateur pour le service d'un autre, elle est donc reliée à un utilisateur (celui qui demande) et à un service (ce qu'il demande)

Une Category peut avoir un parent (association parent), dans ce cas celle-ci est accessible depuis le parent par l'association child

Cas d'utilisations

Acteurs

Les acteurs de l'application peuvent être connecté ou pas. S'ils ne le sont pas ce sont des visiteurs, sinon ce sont des utilisateurs ou des administrateurs.

La hiérarchie des acteurs est définie comme ceci : les utilisateurs peuvent faire plus de choses que les visiteurs et les administrateurs plus de choses que les utilisateurs.

Actions

Ce que le visiteur peut faire

  • Accéder à la page d'accueil, qui présente le site
  • S'inscrire en tant qu'utilisateur
  • Se connecter pour devenir utilisateur ou administrateur
  • Faire une demande de mot de passe oublié
  • Afficher la liste des services proposés par les utilisateurs de la communauté (possibilité de filtrer selon différents critères)
  • Afficher les détails d'un service

Ce que l'utilisateur peut faire

  • Tout ce que peut faire le visiteur à part s'inscrire, se connecter ou faire une demande de mot de passe oublié
  • Afficher le profil d'un utilisateur
  • Modifier son profil d'utilisateur
  • Proposer un service à la communauté
  • Demander le service d'un autre utilisateur
  • Accepter ou refuser la demande de service d'un autre utilisateur
  • Terminer ou annuler un service ayant été accepté (pour signaler que celui ci s'est bien déroulé ou ne s'est pas fait)

Ce que l'administrateur peut faire

  • Tout ce que peut faire l'utilisateur
  • Afficher la liste des utilisateurs
  • Envoyer un email à un utilisateur (les adresses emails peuvent être masquées aux utilisateurs)
  • Modifier le profil d'un utilisateur
  • Afficher la liste des catégories de service
  • Ajouter des catégories
  • Modifier des catégories
  • Supprimer des catégories

Scénarios de cas concret

Pour proposer un service, l'utilisateur se rend sur la page correspondante (en cliquant sur le lien présent dans le menu en haut de page), rempli les informations requises et valide.

Pour découvrir des services, l'utilisateur se rend sur la page listant tous les services (également présent dans le menu du haut) et accède à un tableau contenant les services des autres utilisateurs (pas les siens) dont il n'est pas en train de faire la demande. Les services dont il a déjà fait la demande (et que celle-ci est terminée) sont également affichés : il a le droit de redemander un même service. Cette page permet à l'utilisateur de filtrer la liste des services en fonction du nom, de la ville, du rayon de disponibilité, du prix minimum ou maximum et de la catégorie des services.

Lorsque l'utilisateur a trouvé un service qui l'intéresse, il affiche la page de celui-ci en cliquant sur son nom dans le tableau. Cette page affiche entre autres la description complète du service, et un bouton permettant de demander ce service sur lequel il clique.

Une fois le service demandé, celui-ci apparait maintenant "en attente de validation" sur la page des demandes accessible par le menu du haut. Cette page comporte deux colonnes : les demandes entrantes correspondant aux demandes des autres utilisateurs pour les service de celui actuellement connecté, et les demandes sortantes correspondant aux demandes que l'utilisateur connecté a demandé aux autres.

L'utilisateur se voyant demander un service aura donc une entrée dans le tableau des demandes entrantes, qu'il pourra accepter ou rejeter. Pour faire son choix il peut voir le message que lui a envoyé cet utilisateur ayant fait sa demande, et accéder à son profil où il pourra voir l'état de son porte monnaie (et savoir si c'est un utilisateur qui contribue ou non au bon fonctionnement du site). Un mail est envoyé à l'utilisateur demandant lorsque la demande est acceptée ou refusée.

Si la demande d'un utilisateur est refusée, elle n'apparait plus dans ses demandes sortantes. Si elle est acceptée, l'état "en attente de validation" laisse place à deux boutons permettant de terminer (dans le cas où il s'est bien déroulé) ou annuler (dans le cas où il ne s'est pas fait) le service. Dans les deux cas un mail est envoyé à l'utilisateur proposant le service pour l'informer.

Si l'utilisateur décide de terminer un service, le montant du service est crédité à l'utilisateur proposant et débité à l'utilisateur demandant le service.

Screencasts

Nous avons réalisé différents screencasts de l'application en exécution :

Informations

 Développement

Technologies Utilisés

Symfony 2

Symfony est un framework écrit en PHP pour aider à la réalisation des sites web. La version utilisée est la version 2.6.

Lien : https://symfony.com/

Compass

Compass est un framework CSS qui facilite l'écriture des feuilles de styles. Il permet notamment d'utiliser de façon plus intuitive "l'imbrication" des styles.

Lien : http://compass-style.org/

Bootstrap

Bootstrap est un framework HTML/CSS/JS qui facilite le design des applications web. Il permet également, entre autres, de faire nativement du responsive design.

Lien : http://getbootstrap.com/

Composer

Composer est un outil qui permet de gérer les dépendances pour le langages PHP pour les bibliothèques utiles afin de faciliter le développement du projet. Il suffit de préciser dans la configuration les bibliothèques nécessaire et Composer les installe.

Lien : https://getcomposer.org/

Bower

Bower est aux bibliothèques CSS/JS ce que Composer est aux bibliothèques PHP : un gestionnaire de paquets permettant facilement d'installer toute sorte de bibliothèque CSS et/ou JS

Lien : http://bower.io/

Doctrine

Doctrine est projet qui rassemble des bibliothèques PHP qui permettent de gérer le mapping relationnel entre PHP et la base de donnée.

Lien : http://www.doctrine-project.org/

MySQL

Le système de gestion de bases de données utilisée pour le projet est MySQL.

https://www.mysql.fr/

Installation

Pré-requis

Voici la liste des logiciels à avoir pour pouvoir installer le projet :

Il vous faudra également un compte gmail afin que l'application fonctionne

Installation des dépendances

Une fois le projet téléchargé et décompressé, se placer à la racine et effectuer la commande : php composer.phar install

Cette commande va installer les dépendances à l'aide de composer et bower, plusieurs paramètres vous seront demandés :

  • database_driver : laisser la valeur par défaut
  • database_host : adresse ip ou domaine du serveur stockant la base de données
  • database_port : port de la base de données
  • database_name : nom de la base de données
  • database_user : utilisateur de la base de données
  • database_password : mot de passe de l'utilisateur de la base de données
  • gmail_user : adresse du compte gmail
  • gmail_password : mot de passe du compte gmail (la valeur sera stockée en clair dans le fichier /app/config/parameters.yml et ne sera utilisé que pour la connexion au serveur smtp de google afin de pouvoir envoyer des mails)
  • send_emails : booléen activant l'envoi de mails (laisser true par défaut, sauf si vous savez comment utiliser le profiler de symfony pour aller voir les emails envoyés)
  • locale : laisser fr
  • secret : phrase secrète à changer (générer aléatoirement une chaine d'une 40aine de caractères)
  • compass.bin : chemin de l'éxécutable compass
  • citysearch_api.login : nom d'utilisateur pour l'api citysearch, laisser la valeur par défaut
  • citysearch_api.apikey: mot de passe de l'utilisateur pour l'api citysearch, laisser la valeur par défaut

Installation des assets (css et js)

Exécutez la commande : app/console assetic:dump

Création de la base de données

Pour créer la base de données, lancer cette suite de commandes :

  • app/console doctrine:database:create : crée la base de données
  • app/console doctrine:migrations:migrate : crée les tables dans la base
  • app/console doctrine:fixtures:load : insert des données fictives simulant l'utilisation du site

Accès au site

Configurez votre serveur web afin qu'un virtual host pointe vers le fichier /web/app_dev.php du projet, et accédez à l'url que vous avez défini (n'oubliez pas de faire en sorte que l'accès au domaine redirige bien vers votre machine (fichier /etc/hosts)).

Voici un exemple de virtual host pour nginx :

server {
    listen      80;
    server_name .alternet.dev;
    
    root PATH_TO_ALTERNET/web;
    
    location / {
        try_files $uri /app_dev.php$is_args$args;
    }
    
    location ~ ^/(app_dev|config)\.php(/|$) {
        fastcgi_pass unix:PATH_TO_PHP56_FPM.sock;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS off;
        fastcgi_read_timeout 1h;
    }
    
    error_log PATH_TO_LOG_DIR/alternet_error.log;
    access_log PATH_TO_LOG_DIR/alternet_access.log;
}

Normalement vous pouvez choisir n'importe quel nom de domaine, mais nous vous conseillons d'utiliser alternet.dev sinon l'utilisation de l'API citysearch (http://www.citysearch-api.com/) ne fonctionnera pas avec les identifiants paramétrés par défaut

Jeux de tests

Informations

Les tests ont été développés avec PHPUnit (http://phpunit.de/). Il existe des tests unitaires et des fonctionnels avec Sélénium (http://docs.seleniumhq.org/).

Pour les lancer, utilisez la commande suivante : bin/phpunit -c app/

N'oubliez-pas de lancer le serveur sélénium (http://docs.seleniumhq.org/download/), sans quoi les tests correspondants ne passeront pas.

Il est à noter que nous avons eu un problème étrange avec les tests sélénium sur mac : à chaque ouverture du navigateur apparaissait une fenêtre de rapport de plantage (http://img11.hostingpics.net/pics/455007Capturede769cran20150612a768101018.png) qu'il fallait fermer à chaque fois (c'était bloquant pour continuer les tests). Mais ce problème n'empêche cependant pas la bonne exécution des tests.

Les dossiers de tests sont les dossiers *Bundle/Tests/. Tous les fichiers précisés ci-dessous se situent à l'intérieur.

Tests unitaires

Les tests PHPUnit (non Selenium) sont principalement utilisés pour vérifier la structure de la page et détecter l'incohérence des données côté serveur ainsi que la non-régression.

Les tests PHPUnit simples sont situés dans les fichiers Entity/UserTest.php Security/Voter/UserVoterTest.php.

Tests fonctionnels

Les tests fonctionnels sont gérés par Selenium. Ils vérifient de façon automatique le bon déroulement des cas d'utilisation qu'un visiteur/utilisateur/admin pourrait effectuer ainsi que la non-régression.

Les tests Selenium sont situés dans le dossier Functional/ avec les fichiers AdminWorkflowTest.php, UserWorkflowTest.php et VisitorWorkflowTest.php

Ces tests gèrent la plupart des cas de base.

Test manuels

Également, avant de fournir le livrable, nous avons vérifié manuellement les fonctionnalités. Le premier objectif de ces tests non automatisés était de s'assurer avec un œil humain que chaque fonctionnalité se déroulait au mieux. Le second était de passer outre les limites des tests fonctionnels car ils ne couvrent pas toutes les fonctionnalités.

Le test manuel suivait le scénario, plus quelques autres cas d'erreur.

Utilisation

Les fixtures que vous avez enregistré contiennent deux utilisateurs ayant pour identifiants user@alternet.dev (mdp: user) et admin@alternet.dev (mdp: admin). Ils sont importants pour les tests avec sélénium donc veillez à ne pas les supprimer.

Ils ont tous deux un service d'enregistré à leur compte, vous pourrez donc vous connecter en tant que l'un des deux et demander le service de l'autre. Attention cependant, cette manipulation n'est pas conseillée à cause des adresses emails de ces deux comptes.

Nous vous conseillons par contre d'inscrire deux nouveaux utilisateurs avec des adresses emails dont vous pouvez consulter le contenu (http://www.yopmail.fr/ pourrait aider) et testez les fonctionnalités du site avec ces deux utilisateurs.

Avancement

Statistiques

Par rapport aux cas d'utilisation attendus, voici l'avancement du projet.

  • Environnement de développement
    100 %
  • Structure
    100 %
  • Développement
    100 %
    • Backend
      100 %
      • Gestion des services
      • Gestion des utilisateurs (création et profils)
      • Gestion des rôles et des permissions
      • Gestion des catégories
      • Gestion des demandes
    • Frontend
      100 %
      • Page principale et page de recherche quel que soit le rôle
      • Pages utilisateur (proposer un service et gérer ses demandes, ainsi que son profil)
      • Pages administrateur (pages utilisateur + ajouter des catégories et modifier les utilisateurs)
  • Design
    100 %
  • Tests
    62.5 %
    • Unitaires
      40 %
    • Fonctionnels
      85 %

Réponse aux contraintes du projet

Les contraintes imposées pour le projet sont précisées ci-dessous. Le projet répond à la quasi-totalité des demandes imposés et quelques demandes souhaités en plus.

Utilisation d'un framework

Nous avons utilisé Symfony 2, qui utilise un patron de type modèle-vue-contrôleur.

Gestion des rôles avec des utilisateurs différents ayant des droits et des rôles différenciés

Le projet gère 2 rôles précis pour les utilisateurs inscrits et nous pouvons dégager 3 rôles différents au total. Les voici par ordre de hiérarchie des actions possibles.

Visiteur

Les visiteur peuvent seulement accéder au site pour consulter les services disponibles. Ils peuvent également s'inscrire ou se connecter (pour ce dernier cas, cela signifie qu'il s'agit d'un utilisateur ou administrateur).

Utilisateur

Les utilisateurs peuvent faire ce que les visiteurs peuvent faire. Ils sont également capable de proposer un service à la communauté ainsi que de gérer les demandes qui leur sont faites. Ils peuvent aussi demander un service. Un utilisateur peut éditer son profil et consulter celui des autres utilisateurs.

Administrateur

Les administrateurs peuvent faire ce que les utilisateurs peuvent faire. De plus, ils peuvent ajouter des catégories qui permettent de définir avec plus de précision les services. Ils sont également capable de modifier le profil des autres utilisateurs.

Site adapté à plusieurs terminaux dont une version mobile

Grâce à Bootstrap, le design du site s'adapte en fonction de la taille de la fenêtre.

Mise en place de jeux de tests unitaires : pour tester la partie modèle et contrôleur

Il y a, côté backend, plusieurs tests unitaires pour vérifier les détails les plus important du projet. Idéalement, il en manque un certain nombre pour être complètement exhaustif.

Mise en place de jeux de tests fonctionnels avec des technologies de type Selenium

Le projet a plusieurs tests automatisés avec Selenium pour tester le frontend. La quasi-totalité des cheminements possibles des actions des utilisateurs ont été traités. Il manque idéalement les cas d'erreurs et les cas de création (services & categories), qui ont été testé manuellement.

Utilisation d'un webservice

Lors du choix d'une ville pour le lieu d'un utilisateur ou pour le lieu à partir duquel est proposé un service, nous utilisons city-search en effectuant des requêtes Ajax pour récupérer le nom des villes avec exactitude.

Améliorations envisageables

Tests

Avant toute chose, il est évident au regard de l'avancement que des tests supplémentaires auraient pu être ajouté. Le manque de temps ne nous a pas permit de vérifier automatiquement de façon exhaustive chaque fonctionnalité.

Celles-ci ont toutefois toutes été testées manuellement au moins une fois.

Fonctionnalités

Il existe plusieurs fonctionnalités que nous aurions aimé considérer si le projet avait été plus long. Nous pensons que ces fonctionnalités seraient une évolution logique pour le site web.

Commentaires sur les demandes

Il faudrait que les utilisateurs puissent commenter les services proposés et les demandes. Cela permettrait de donner son avis sur l'objet de la demande. De plus cela permettrait de créer une discussion entre demandeur et offreur, afin de convenir du meilleur échange possible pour le service.

Cela pourrait créer un rôle additionnel de modérateur.

Réputation

Les utilisateurs devraient pouvoir noter les autres utilisateurs en terme de confiance que l'on peut leur accorder (par exemple s'il respectent leur délais, si les services qu'ils proposent sont bien décrits, etc.). Ils devraient le cas échéant justifier leur note par un texte court.

Service avancés

Les services pourraient être améliorés par les idées suivantes :

  • (Meilleure) gestion au niveau du point de rendez-vous ou tout ce qui pourrait faciliter l'échange entre les personnes.
  • Possibilité d'ajouter certains champs pour certains type de services (exemple : gestion des stocks).
  • Possibilité d'ajouter ou d'enlever des descriptifs (exemples : stockable, immatériel, déplaçable...)
  • Possibilité de proposer des requêtes de service (exemple : "Offre 5.0 pour que quelqu'un récupère un colis en point relais pour moi.")