Ce projet a été généré avec Nx. Il est décomposé en 3 sous projets:
- dougs-mouvements-validation-server: Le serveur NodeJS/Express à l'adresse http://localhost:3333
- dougs-mouvements-validation-app: L'application Angular à l'adresse http://localhost:4200
- dougs-mouvements-validation-lib: Librairie partagée entre les deux applications content les modèles
Le serveur NodeJS et l'application Angular ont été entièrement testés.
J'ai décidé de ne pas me contenter de faire un serveur avec une API mais aussi de faire une application Front Angular
pour avoir un environnement de test et de visualisation des inputs/outputs.
C'est ce qui explique l'utilisation de NX qui est un outil permettant une gestion simplifiée des "mono repo".
Il permet notament une gestion ultra simple des librairies partagées.
Dans l'application Angular, j'ai intégré des cas d'utilisations déjà préparés: inputs minimum, inputs valides et inputs erronés.
Chacun de ces inputs peut être affiché au click d'un bouton et
chacune de ces requêtes peut être testée et sa réponse visualisée sous une forme plus ergonomique.
J'ai aussi laissé un cas d'utilisation personnalisé où
il est possible d'importer ses propres paramètres dans une variable directement dans les sources
(apps/dougs-mouvements-validation-app/src/app.component.ts -> customBody).
Si aucun paramètre n'a été importé, ces informations sont rappelées.
Ces paramètres importés sont visualisables et testable de la même manière.
NodeJS version >= "12.0.0" (nécessaire pour le lancement des tests uniquement)
npm install
ouyarn
pour installer les dépendances nécessairesnpm run start-all
ouyarn start-all
pour lancer le server et l'application angular simultanémentnpm run test-all
ouyarn test-all
pour lancer le testing complet des deux applicationsnpm run nx serve [PROEJCT_NAME]
ouyarn nx serve [PROEJCT_NAME]
pour lancer une application uniquementnpm run nx test [PROEJCT_NAME]
ouyarn nx test [PROEJCT_NAME]
pour tester une application uniquement
Suite à mon analyse du problème, voici la liste des assomptions du serveur:
- Le body de la requête POST sur la route /api/movements/validation doit être bien formé suivant le modèle donné.
- La liste des points de contrôle doit nécessairement contenir 2 objets au minimum
- Les listes d'objets fournis sont triés par ordre croissant chronologiquement
- La liste d'opération est chronologiquement comprise entre le premier et le dernier point de contrôle
Cette liste relativement stricte permet de diminuer considérablement la complexité algorithmique tout en restant réaliste vis à vis du problème donné.
Request body:
{ “operations”: [{ id, date, wording, amount }], “checkpoints”: [{ date, balance }] }
Responses:
Code 202: { “message”: "Accepted", "isValid": true, "reasons": [] }
Code 418: { “message”: "I’m a teapot", "isValid": false, “reasons”: Reason[] }
Code 419: { “message”: "Wrong parameters, an error occured", "type": "INTERNAL_ERROR" }
Reason model
interface Reason { "type": string; "message": string; "missingOperations"?: MissingOperation; "duplicatedOperation"?: Operation; }
MissingOperation model
interface MissingOperation { "startDate": string | Date; "endDate": string | Date; "difference": number; }
Grâce aux assomptions cités ci-dessus la complexité de l'algorithme est de o(n).
Les deux premiers points de contrôle sont initialisés instantanément et le serveur boucle ensuite sur la liste d'opérations.
Il y a une séparation des cas sur la comparaison entre la date de l'opération et la date du point de contrôle. Si la date est antérieure, elle est ajouté au compte dynamique.
Dans le cas contraire, un bilan est fait entre le compte dynamique et le point de contrôle. Puis on passe au point de contrôle suivant.
Enfin, si un enchainement de point de contrôles est présent après la dernière opération, il pris en compte en itérant sur les points de contrôles "restants".
Jest/Supertest/Jasmine
Fichier: server.test.ts
Jest/Jasmine
Fichiers: *.spec.ts
File | Statements | Branches | Functions | Lines | |||||
---|---|---|---|---|---|---|---|---|---|
app |
|
100% | 20/20 | 100% | 12/12 | 100% | 5/5 | 100% | 18/18 |
app/components/input-visualiser |
|
100% | 19/19 | 100% | 11/11 | 100% | 4/4 | 100% | 17/17 |
app/components/validation-visualiser |
|
100% | 14/14 | 100% | 0/0 | 100% | 8/8 | 100% | 10/10 |
app/constants |
|
100% | 3/3 | 100% | 0/0 | 100% | 0/0 | 100% | 3/3 |
app/services |
|
100% | 12/12 | 100% | 2/2 | 100% | 2/2 | 100% | 10/10 |
File | Statements | Branches | Functions | Lines | |||||
---|---|---|---|---|---|---|---|---|---|
controllers |
|
100% | 15/15 | 100% | 4/4 | 100% | 2/2 | 100% | 14/14 |
routes |
|
100% | 12/12 | 100% | 0/0 | 100% | 1/1 | 100% | 12/12 |
services |
|
100% | 38/38 | 100% | 8/8 | 100% | 10/10 | 100% | 38/38 |
utils |
|
100% | 5/5 | 100% | 0/0 | 100% | 1/1 | 100% | 5/5 |