From e6b2a92f7fa3da87065d025812f46f723758aecd Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 12:57:14 +0200
Subject: [PATCH 01/19] base of the test with out serial number

---
 tests/test_snapshot.py | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 4482e66e..4f55a53e 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -473,3 +473,16 @@ def test_pc_rating_rate_none(user: UserClient):
 def test_pc_2(user: UserClient):
     s = file('laptop-hp_255_g3_notebook-hewlett-packard-cnd52270fw.snapshot')
     snapshot, _ = user.post(res=Snapshot, data=s)
+
+
+@pytest.mark.one
+def test_backup_snapshot_with_error_500(user: UserClient):
+    snapshot_no_hid = file('basic.snapshot.nohid')
+    response_snapshot, response_status = user.post(res=Snapshot, data=snapshot_no_hid)
+    assert response_snapshot['software'] == 'Workbench'
+    assert response_snapshot['version'] == '11.0b9'
+    assert response_snapshot['uuid'] == '9a3e7485-fdd0-47ce-bcc7-65c55226b598'
+    assert response_snapshot['elapsed'] == 4
+    assert response_snapshot['author']['id'] == user.user['id']
+    assert response_snapshot['severity'] == 'Warning'
+    assert response_status.status_code == 201

From 236806466ab0bff458a4d195845caad0257bd036 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 18:28:07 +0200
Subject: [PATCH 02/19] test backup snapshot

---
 tests/test_snapshot.py | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 4f55a53e..7ea66aa9 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -22,6 +22,7 @@ from ereuse_devicehub.resources.device.sync import MismatchBetweenProperties, \
 from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware
 from ereuse_devicehub.resources.tag import Tag
 from ereuse_devicehub.resources.user.models import User
+from ereuse_devicehub.resources.views import TMP_SNAPSHOTS
 from tests.conftest import file
 
 
@@ -477,12 +478,20 @@ def test_pc_2(user: UserClient):
 
 @pytest.mark.one
 def test_backup_snapshot_with_error_500(user: UserClient):
+    """ This test check if the file snapshot is create when some snapshot is wrong """
     snapshot_no_hid = file('basic.snapshot.nohid')
-    response_snapshot, response_status = user.post(res=Snapshot, data=snapshot_no_hid)
-    assert response_snapshot['software'] == 'Workbench'
-    assert response_snapshot['version'] == '11.0b9'
-    assert response_snapshot['uuid'] == '9a3e7485-fdd0-47ce-bcc7-65c55226b598'
-    assert response_snapshot['elapsed'] == 4
-    assert response_snapshot['author']['id'] == user.user['id']
-    assert response_snapshot['severity'] == 'Warning'
-    assert response_status.status_code == 201
+    _, response_status = user.post(res=Snapshot, data=snapshot_no_hid)
+    uuid = '9a3e7485-fdd0-47ce-bcc7-65c55226b598'
+    files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
+
+    snapshot = {'software': '', 'version': '', 'uuid': ''}
+    if files:
+        path_snapshot = "{dir}/{file}".format(dir=TMP_SNAPSHOTS, file=files[0])
+        file_snapshot = open(path_snapshot)
+        snapshot = json.loads(file_snapshot.read())
+        file_snapshot.close()
+
+    assert snapshot['software'] == 'Workbench'
+    assert snapshot['version'] == '11.0b9'
+    assert snapshot['uuid'] == uuid
+    assert response_status.status_code == 500

From 9a24eb5fd53f5b7fa5f9f0ad6be2c9ac1937aaf5 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 18:28:57 +0200
Subject: [PATCH 03/19] save snapshot in a temporal file

---
 ereuse_devicehub/resources/action/views.py | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index ba727dc3..5c7e5a53 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -1,3 +1,5 @@
+import os
+from time import time
 from distutils.version import StrictVersion
 from typing import List
 from uuid import UUID
@@ -17,6 +19,23 @@ from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
 
 SUPPORTED_WORKBENCH = StrictVersion('11.0')
 
+TMP_SNAPSHOTS = 'tmp/snapshots'
+
+
+def save_snapshot_on_file(snapshot_json):
+    """
+    This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
+    The file need to be saved with one name format with the stamptime and uuid joins
+    """
+    if not os.path.isdir(TMP_SNAPSHOTS):
+        os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
+
+    name_file = "{uuid}_{time}.json".format(uuid=snapshot_json['uuid'], time=int(time()))
+    path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file)
+    snapshot_file = open(path_name, 'w')
+    snapshot_file.write(json.dumps(snapshot_json))
+    snapshot_file.close()
+
 
 class ActionView(View):
     def post(self):

From aed9e8c2d60fa1fb96d2b5fb1f69a66727b54d8f Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 18:29:18 +0200
Subject: [PATCH 04/19] change name

---
 ereuse_devicehub/resources/action/views.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 5c7e5a53..4c83f2a8 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -22,7 +22,7 @@ SUPPORTED_WORKBENCH = StrictVersion('11.0')
 TMP_SNAPSHOTS = 'tmp/snapshots'
 
 
-def save_snapshot_on_file(snapshot_json):
+def save_snapshot_in_file(snapshot_json):
     """
     This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
     The file need to be saved with one name format with the stamptime and uuid joins

From 00ab0d7b2aee764ac0384644e9e76e8c39239fe4 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 18:36:37 +0200
Subject: [PATCH 05/19] add tmp to gitignore

---
 .gitignore | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.gitignore b/.gitignore
index 69f6d4be..6a130a6e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,3 +116,6 @@ ENV/
 
 # Environment
 .env
+
+# Temporal dir
+tmp/

From 56907e70558b4da45c790fa2038e5e1400e76f92 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 18:37:23 +0200
Subject: [PATCH 06/19] fixed bug

---
 ereuse_devicehub/resources/action/views.py | 1 +
 1 file changed, 1 insertion(+)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 4c83f2a8..27dfce58 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -1,4 +1,5 @@
 import os
+import json
 from time import time
 from distutils.version import StrictVersion
 from typing import List

From 420b7ad4ab4dffe694d7f8d341b1c82e75ed0cdb Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 19:05:52 +0200
Subject: [PATCH 07/19] adding test_save_snapshot_in_file

---
 tests/test_snapshot.py | 30 ++++++++++++++++++++++++++++--
 1 file changed, 28 insertions(+), 2 deletions(-)

diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 7ea66aa9..e0c5b06f 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -1,9 +1,12 @@
+import os
+import json
+import pytest
+
 from datetime import datetime, timedelta, timezone
 from operator import itemgetter
 from typing import List, Tuple
 from uuid import uuid4
 
-import pytest
 from boltons import urlutils
 from teal.db import UniqueViolation, DBError
 from teal.marshmallow import ValidationError
@@ -22,7 +25,7 @@ from ereuse_devicehub.resources.device.sync import MismatchBetweenProperties, \
 from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware
 from ereuse_devicehub.resources.tag import Tag
 from ereuse_devicehub.resources.user.models import User
-from ereuse_devicehub.resources.views import TMP_SNAPSHOTS
+from ereuse_devicehub.resources.action.views import TMP_SNAPSHOTS, save_snapshot_in_file
 from tests.conftest import file
 
 
@@ -476,6 +479,28 @@ def test_pc_2(user: UserClient):
     snapshot, _ = user.post(res=Snapshot, data=s)
 
 
+@pytest.mark.ones
+def test_save_snapshot_in_file():
+    """ This test check if works the function save_snapshot_in_file """
+    snapshot_no_hid = file('basic.snapshot.nohid')
+    save_snapshot_in_file(snapshot_no_hid)
+
+    uuid = snapshot_no_hid['uuid']
+    files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
+
+    snapshot = {'software': '', 'version': '', 'uuid': ''}
+    if files:
+        path_snapshot = "{dir}/{file}".format(dir=TMP_SNAPSHOTS, file=files[0])
+        file_snapshot = open(path_snapshot)
+        snapshot = json.loads(file_snapshot.read())
+        file_snapshot.close()
+        os.remove(path_snapshot)
+
+    assert snapshot['software'] == snapshot_no_hid['software']
+    assert snapshot['version'] == snapshot_no_hid['version']
+    assert snapshot['uuid'] == uuid
+
+
 @pytest.mark.one
 def test_backup_snapshot_with_error_500(user: UserClient):
     """ This test check if the file snapshot is create when some snapshot is wrong """
@@ -490,6 +515,7 @@ def test_backup_snapshot_with_error_500(user: UserClient):
         file_snapshot = open(path_snapshot)
         snapshot = json.loads(file_snapshot.read())
         file_snapshot.close()
+        os.remove(path_snapshot)
 
     assert snapshot['software'] == 'Workbench'
     assert snapshot['version'] == '11.0b9'

From e36256ee72170ce466b54d24c77736fd50d78a69 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 19:28:52 +0200
Subject: [PATCH 08/19] clean test

---
 tests/test_snapshot.py | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index e0c5b06f..cd80ae0f 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -479,7 +479,7 @@ def test_pc_2(user: UserClient):
     snapshot, _ = user.post(res=Snapshot, data=s)
 
 
-@pytest.mark.ones
+@pytest.mark.mvp
 def test_save_snapshot_in_file():
     """ This test check if works the function save_snapshot_in_file """
     snapshot_no_hid = file('basic.snapshot.nohid')
@@ -506,7 +506,7 @@ def test_backup_snapshot_with_error_500(user: UserClient):
     """ This test check if the file snapshot is create when some snapshot is wrong """
     snapshot_no_hid = file('basic.snapshot.nohid')
     _, response_status = user.post(res=Snapshot, data=snapshot_no_hid)
-    uuid = '9a3e7485-fdd0-47ce-bcc7-65c55226b598'
+    uuid = snapshot_no_hid['uuid']
     files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
 
     snapshot = {'software': '', 'version': '', 'uuid': ''}
@@ -517,7 +517,7 @@ def test_backup_snapshot_with_error_500(user: UserClient):
         file_snapshot.close()
         os.remove(path_snapshot)
 
-    assert snapshot['software'] == 'Workbench'
-    assert snapshot['version'] == '11.0b9'
+    assert snapshot['software'] == snapshot_no_hid['software']
+    assert snapshot['version'] == snapshot_no_hid['version']
     assert snapshot['uuid'] == uuid
     assert response_status.status_code == 500

From 0e89af12152949c9bfe94965f3be5c824a56f46e Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 7 Oct 2020 19:58:09 +0200
Subject: [PATCH 09/19] catch all exceptions and save de snapshot

---
 ereuse_devicehub/resources/action/views.py | 113 +++++++++++----------
 1 file changed, 60 insertions(+), 53 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 27dfce58..5f825550 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -1,5 +1,6 @@
 import os
 import json
+import copy
 from time import time
 from distutils.version import StrictVersion
 from typing import List
@@ -28,11 +29,12 @@ def save_snapshot_in_file(snapshot_json):
     This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
     The file need to be saved with one name format with the stamptime and uuid joins
     """
+    name_file = "{uuid}_{time}.json".format(uuid=snapshot_json['uuid'], time=int(time()))
+    path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file)
+
     if not os.path.isdir(TMP_SNAPSHOTS):
         os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
 
-    name_file = "{uuid}_{time}.json".format(uuid=snapshot_json['uuid'], time=int(time()))
-    path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file)
     snapshot_file = open(path_name, 'w')
     snapshot_file.write(json.dumps(snapshot_json))
     snapshot_file.close()
@@ -78,62 +80,67 @@ class ActionView(View):
         # model object, when we flush them to the db we will flush
         # snapshot, and we want to wait to flush snapshot at the end
 
-        device = snapshot_json.pop('device')  # type: Computer
-        components = None
-        if snapshot_json['software'] == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid):
-            components = snapshot_json.pop('components', None)  # type: List[Component]
-        snapshot = Snapshot(**snapshot_json)
+        snapshot_json_bakup = copy.copy(snapshot_json)
+        try:
+            device = snapshot_json.pop('device')  # type: Computer
+            components = None
+            if snapshot_json['software'] == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid):
+                components = snapshot_json.pop('components', None)  # type: List[Component]
+            snapshot = Snapshot(**snapshot_json)
 
-        # Remove new actions from devices so they don't interfere with sync
-        actions_device = set(e for e in device.actions_one)
-        device.actions_one.clear()
-        if components:
-            actions_components = tuple(set(e for e in c.actions_one) for c in components)
-            for component in components:
-                component.actions_one.clear()
+            # Remove new actions from devices so they don't interfere with sync
+            actions_device = set(e for e in device.actions_one)
+            device.actions_one.clear()
+            if components:
+                actions_components = tuple(set(e for e in c.actions_one) for c in components)
+                for component in components:
+                    component.actions_one.clear()
 
-        assert not device.actions_one
-        assert all(not c.actions_one for c in components) if components else True
-        db_device, remove_actions = resource_def.sync.run(device, components)
+            assert not device.actions_one
+            assert all(not c.actions_one for c in components) if components else True
+            db_device, remove_actions = resource_def.sync.run(device, components)
 
-        del device  # Do not use device anymore
-        snapshot.device = db_device
-        snapshot.actions |= remove_actions | actions_device  # Set actions to snapshot
-        # commit will change the order of the components by what
-        # the DB wants. Let's get a copy of the list so we preserve order
-        ordered_components = OrderedSet(x for x in snapshot.components)
+            del device  # Do not use device anymore
+            snapshot.device = db_device
+            snapshot.actions |= remove_actions | actions_device  # Set actions to snapshot
+            # commit will change the order of the components by what
+            # the DB wants. Let's get a copy of the list so we preserve order
+            ordered_components = OrderedSet(x for x in snapshot.components)
 
-        # Add the new actions to the db-existing devices and components
-        db_device.actions_one |= actions_device
-        if components:
-            for component, actions in zip(ordered_components, actions_components):
-                component.actions_one |= actions
-                snapshot.actions |= actions
+            # Add the new actions to the db-existing devices and components
+            db_device.actions_one |= actions_device
+            if components:
+                for component, actions in zip(ordered_components, actions_components):
+                    component.actions_one |= actions
+                    snapshot.actions |= actions
 
-        if snapshot.software == SnapshotSoftware.Workbench:
-            # Check ownership of (non-component) device to from current.user
-            if db_device.owner_id != g.user.id:
-                raise InsufficientPermission()
-            # Compute ratings
-            try:
-                rate_computer, price = RateComputer.compute(db_device)
-            except CannotRate:
-                pass
-            else:
-                snapshot.actions.add(rate_computer)
-                if price:
-                    snapshot.actions.add(price)
-        elif snapshot.software == SnapshotSoftware.WorkbenchAndroid:
-            pass  # TODO try except to compute RateMobile
-        # Check if HID is null and add Severity:Warning to Snapshot
-        if snapshot.device.hid is None:
-            snapshot.severity = Severity.Warning
-        db.session.add(snapshot)
-        db.session().final_flush()
-        ret = self.schema.jsonify(snapshot)  # transform it back
-        ret.status_code = 201
-        db.session.commit()
-        return ret
+            if snapshot.software == SnapshotSoftware.Workbench:
+                # Check ownership of (non-component) device to from current.user
+                if db_device.owner_id != g.user.id:
+                    raise InsufficientPermission()
+                # Compute ratings
+                try:
+                    rate_computer, price = RateComputer.compute(db_device)
+                except CannotRate:
+                    pass
+                else:
+                    snapshot.actions.add(rate_computer)
+                    if price:
+                        snapshot.actions.add(price)
+            elif snapshot.software == SnapshotSoftware.WorkbenchAndroid:
+                pass  # TODO try except to compute RateMobile
+            # Check if HID is null and add Severity:Warning to Snapshot
+            if snapshot.device.hid is None:
+                snapshot.severity = Severity.Warning
+            db.session.add(snapshot)
+            db.session().final_flush()
+            ret = self.schema.jsonify(snapshot)  # transform it back
+            ret.status_code = 201
+            db.session.commit()
+            return ret
+        except Exception as err:
+            save_snapshot_in_file(snapshot_json_bakup)
+            raise err
 
     def transfer_ownership(self):
         """Perform a InitTransfer action to change author_id of device"""

From 258c3b4efd134f45c736756f74175e0c23b325c2 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Thu, 8 Oct 2020 14:47:11 +0200
Subject: [PATCH 10/19] more simple patch in post view

---
 ereuse_devicehub/resources/action/views.py | 123 +++++++++++----------
 1 file changed, 62 insertions(+), 61 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 5f825550..a154164b 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -1,6 +1,5 @@
 import os
 import json
-import copy
 from time import time
 from distutils.version import StrictVersion
 from typing import List
@@ -8,6 +7,7 @@ from uuid import UUID
 
 from flask import current_app as app, request, g
 from sqlalchemy.util import OrderedSet
+from marshmallow.exceptions import ValidationError as mValidationError
 from teal.marshmallow import ValidationError
 from teal.resource import View
 
@@ -24,26 +24,28 @@ SUPPORTED_WORKBENCH = StrictVersion('11.0')
 TMP_SNAPSHOTS = 'tmp/snapshots'
 
 
-def save_snapshot_in_file(snapshot_json):
+def save_json(req_json):
     """
     This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
     The file need to be saved with one name format with the stamptime and uuid joins
     """
-    name_file = "{uuid}_{time}.json".format(uuid=snapshot_json['uuid'], time=int(time()))
+    name_file = "{uuid}_{time}.json".format(uuid=req_json.get('uuid', ''), time=int(time()))
     path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file)
 
     if not os.path.isdir(TMP_SNAPSHOTS):
         os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
 
     snapshot_file = open(path_name, 'w')
-    snapshot_file.write(json.dumps(snapshot_json))
+    snapshot_file.write(json.dumps(req_json))
     snapshot_file.close()
+    return path_name
 
 
 class ActionView(View):
     def post(self):
         """Posts an action."""
         json = request.get_json(validate=False)
+        path_snapshot = save_json(json)
         if not json or 'type' not in json:
             raise ValidationError('Resource needs a type.')
         # todo there should be a way to better get subclassess resource
@@ -51,11 +53,14 @@ class ActionView(View):
         resource_def = app.resources[json['type']]
         a = resource_def.schema.load(json)
         if json['type'] == Snapshot.t:
-            return self.snapshot(a, resource_def)
+            response = self.snapshot(a, resource_def)
+            os.remove(path_snapshot)
+            return response
         if json['type'] == VisualTest.t:
             pass
             # TODO JN add compute rate with new visual test and old components device
         if json['type'] == InitTransfer.t:
+            os.remove(path_snapshot)
             return self.transfer_ownership()
         Model = db.Model._decl_class_registry.data[json['type']]()
         action = Model(**a)
@@ -64,6 +69,7 @@ class ActionView(View):
         ret = self.schema.jsonify(action)
         ret.status_code = 201
         db.session.commit()
+        os.remove(path_snapshot)
         return ret
 
     def one(self, id: UUID):
@@ -80,67 +86,62 @@ class ActionView(View):
         # model object, when we flush them to the db we will flush
         # snapshot, and we want to wait to flush snapshot at the end
 
-        snapshot_json_bakup = copy.copy(snapshot_json)
-        try:
-            device = snapshot_json.pop('device')  # type: Computer
-            components = None
-            if snapshot_json['software'] == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid):
-                components = snapshot_json.pop('components', None)  # type: List[Component]
-            snapshot = Snapshot(**snapshot_json)
+        device = snapshot_json.pop('device')  # type: Computer
+        components = None
+        if snapshot_json['software'] == (SnapshotSoftware.Workbench or SnapshotSoftware.WorkbenchAndroid):
+            components = snapshot_json.pop('components', None)  # type: List[Component]
+        snapshot = Snapshot(**snapshot_json)
 
-            # Remove new actions from devices so they don't interfere with sync
-            actions_device = set(e for e in device.actions_one)
-            device.actions_one.clear()
-            if components:
-                actions_components = tuple(set(e for e in c.actions_one) for c in components)
-                for component in components:
-                    component.actions_one.clear()
+        # Remove new actions from devices so they don't interfere with sync
+        actions_device = set(e for e in device.actions_one)
+        device.actions_one.clear()
+        if components:
+            actions_components = tuple(set(e for e in c.actions_one) for c in components)
+            for component in components:
+                component.actions_one.clear()
 
-            assert not device.actions_one
-            assert all(not c.actions_one for c in components) if components else True
-            db_device, remove_actions = resource_def.sync.run(device, components)
+        assert not device.actions_one
+        assert all(not c.actions_one for c in components) if components else True
+        db_device, remove_actions = resource_def.sync.run(device, components)
 
-            del device  # Do not use device anymore
-            snapshot.device = db_device
-            snapshot.actions |= remove_actions | actions_device  # Set actions to snapshot
-            # commit will change the order of the components by what
-            # the DB wants. Let's get a copy of the list so we preserve order
-            ordered_components = OrderedSet(x for x in snapshot.components)
+        del device  # Do not use device anymore
+        snapshot.device = db_device
+        snapshot.actions |= remove_actions | actions_device  # Set actions to snapshot
+        # commit will change the order of the components by what
+        # the DB wants. Let's get a copy of the list so we preserve order
+        ordered_components = OrderedSet(x for x in snapshot.components)
 
-            # Add the new actions to the db-existing devices and components
-            db_device.actions_one |= actions_device
-            if components:
-                for component, actions in zip(ordered_components, actions_components):
-                    component.actions_one |= actions
-                    snapshot.actions |= actions
+        # Add the new actions to the db-existing devices and components
+        db_device.actions_one |= actions_device
+        if components:
+            for component, actions in zip(ordered_components, actions_components):
+                component.actions_one |= actions
+                snapshot.actions |= actions
 
-            if snapshot.software == SnapshotSoftware.Workbench:
-                # Check ownership of (non-component) device to from current.user
-                if db_device.owner_id != g.user.id:
-                    raise InsufficientPermission()
-                # Compute ratings
-                try:
-                    rate_computer, price = RateComputer.compute(db_device)
-                except CannotRate:
-                    pass
-                else:
-                    snapshot.actions.add(rate_computer)
-                    if price:
-                        snapshot.actions.add(price)
-            elif snapshot.software == SnapshotSoftware.WorkbenchAndroid:
-                pass  # TODO try except to compute RateMobile
-            # Check if HID is null and add Severity:Warning to Snapshot
-            if snapshot.device.hid is None:
-                snapshot.severity = Severity.Warning
-            db.session.add(snapshot)
-            db.session().final_flush()
-            ret = self.schema.jsonify(snapshot)  # transform it back
-            ret.status_code = 201
-            db.session.commit()
-            return ret
-        except Exception as err:
-            save_snapshot_in_file(snapshot_json_bakup)
-            raise err
+        if snapshot.software == SnapshotSoftware.Workbench:
+            # Check ownership of (non-component) device to from current.user
+            if db_device.owner_id != g.user.id:
+                raise InsufficientPermission()
+            # Compute ratings
+            try:
+                rate_computer, price = RateComputer.compute(db_device)
+            except CannotRate:
+                pass
+            else:
+                snapshot.actions.add(rate_computer)
+                if price:
+                    snapshot.actions.add(price)
+        elif snapshot.software == SnapshotSoftware.WorkbenchAndroid:
+            pass  # TODO try except to compute RateMobile
+        # Check if HID is null and add Severity:Warning to Snapshot
+        if snapshot.device.hid is None:
+            snapshot.severity = Severity.Warning
+        db.session.add(snapshot)
+        db.session().final_flush()
+        ret = self.schema.jsonify(snapshot)  # transform it back
+        ret.status_code = 201
+        db.session.commit()
+        return ret
 
     def transfer_ownership(self):
         """Perform a InitTransfer action to change author_id of device"""

From 3b93012584db20c144c36b5e2625464927ccb99d Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Thu, 8 Oct 2020 14:48:22 +0200
Subject: [PATCH 11/19] fixing test with a bad snapshot

---
 tests/files/basic.snapshot.badly_formed.yaml | 30 ++++++++++++++++++++
 tests/test_snapshot.py                       | 18 ++++++------
 2 files changed, 40 insertions(+), 8 deletions(-)
 create mode 100644 tests/files/basic.snapshot.badly_formed.yaml

diff --git a/tests/files/basic.snapshot.badly_formed.yaml b/tests/files/basic.snapshot.badly_formed.yaml
new file mode 100644
index 00000000..c63ade42
--- /dev/null
+++ b/tests/files/basic.snapshot.badly_formed.yaml
@@ -0,0 +1,30 @@
+type: Snapshot
+uuid: 9a3e7485-fdd0-47ce-bcc7-65c55226b598
+version: '11.0b9'
+software: Workbench
+elapsed: 4
+device:
+  type: Desktop
+  chassis: Microtower
+  serialNumber: null
+  model: null
+  manufacturer: null
+  actions:
+    - type: VisualTest
+      appearanceRange: A
+      functionalityRange: B
+components:
+  - type: RamModule
+    serialNumber: rm1s
+    model: rm1ml
+    manufacturer: rm1mr
+    speed: 1333
+  - type: Processor
+    serialNumber: p1s
+    model: p1ml
+    manufacturer: p1mr
+    speed: 1.6
+    actions:
+      - type: BenchmarkProcessorr
+        rate: 2410
+        elapsed: 11
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index cd80ae0f..290a7e76 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -3,6 +3,7 @@ import json
 import pytest
 
 from datetime import datetime, timedelta, timezone
+from requests.exceptions import HTTPError
 from operator import itemgetter
 from typing import List, Tuple
 from uuid import uuid4
@@ -25,7 +26,7 @@ from ereuse_devicehub.resources.device.sync import MismatchBetweenProperties, \
 from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware
 from ereuse_devicehub.resources.tag import Tag
 from ereuse_devicehub.resources.user.models import User
-from ereuse_devicehub.resources.action.views import TMP_SNAPSHOTS, save_snapshot_in_file
+from ereuse_devicehub.resources.action.views import TMP_SNAPSHOTS, save_json
 from tests.conftest import file
 
 
@@ -483,7 +484,7 @@ def test_pc_2(user: UserClient):
 def test_save_snapshot_in_file():
     """ This test check if works the function save_snapshot_in_file """
     snapshot_no_hid = file('basic.snapshot.nohid')
-    save_snapshot_in_file(snapshot_no_hid)
+    save_json(snapshot_no_hid)
 
     uuid = snapshot_no_hid['uuid']
     files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
@@ -501,15 +502,17 @@ def test_save_snapshot_in_file():
     assert snapshot['uuid'] == uuid
 
 
-@pytest.mark.one
-def test_backup_snapshot_with_error_500(user: UserClient):
+@pytest.mark.mvp
+def test_backup_snapshot_with_errors(user: UserClient):
     """ This test check if the file snapshot is create when some snapshot is wrong """
-    snapshot_no_hid = file('basic.snapshot.nohid')
-    _, response_status = user.post(res=Snapshot, data=snapshot_no_hid)
+    snapshot_no_hid = file('basic.snapshot.badly_formed')
     uuid = snapshot_no_hid['uuid']
-    files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
 
     snapshot = {'software': '', 'version': '', 'uuid': ''}
+    with pytest.raises(KeyError):
+        response = user.post(res=Snapshot, data=snapshot_no_hid)
+
+    files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
     if files:
         path_snapshot = "{dir}/{file}".format(dir=TMP_SNAPSHOTS, file=files[0])
         file_snapshot = open(path_snapshot)
@@ -520,4 +523,3 @@ def test_backup_snapshot_with_error_500(user: UserClient):
     assert snapshot['software'] == snapshot_no_hid['software']
     assert snapshot['version'] == snapshot_no_hid['version']
     assert snapshot['uuid'] == uuid
-    assert response_status.status_code == 500

From 2a53e1672c018d5733a6c2a7aa778dc51c7d501c Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Fri, 9 Oct 2020 20:29:02 +0200
Subject: [PATCH 12/19] using os.path.join instead of format

---
 ereuse_devicehub/resources/action/views.py | 2 +-
 tests/test_snapshot.py                     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index a154164b..19e5ce30 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -30,7 +30,7 @@ def save_json(req_json):
     The file need to be saved with one name format with the stamptime and uuid joins
     """
     name_file = "{uuid}_{time}.json".format(uuid=req_json.get('uuid', ''), time=int(time()))
-    path_name = "{tmp}/{file}".format(tmp=TMP_SNAPSHOTS, file=name_file)
+    path_name = os.path.join(tmp=TMP_SNAPSHOTS, file=name_file)
 
     if not os.path.isdir(TMP_SNAPSHOTS):
         os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 290a7e76..b3157d38 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -491,7 +491,7 @@ def test_save_snapshot_in_file():
 
     snapshot = {'software': '', 'version': '', 'uuid': ''}
     if files:
-        path_snapshot = "{dir}/{file}".format(dir=TMP_SNAPSHOTS, file=files[0])
+        path_snapshot = os.path.join(dir=TMP_SNAPSHOTS, file=files[0])
         file_snapshot = open(path_snapshot)
         snapshot = json.loads(file_snapshot.read())
         file_snapshot.close()
@@ -514,7 +514,7 @@ def test_backup_snapshot_with_errors(user: UserClient):
 
     files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
     if files:
-        path_snapshot = "{dir}/{file}".format(dir=TMP_SNAPSHOTS, file=files[0])
+        path_snapshot = os.path.join(dir=TMP_SNAPSHOTS, file=files[0])
         file_snapshot = open(path_snapshot)
         snapshot = json.loads(file_snapshot.read())
         file_snapshot.close()

From 99a12b2b220d01e8f05541b8a01a8fac28bfb003 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Fri, 9 Oct 2020 20:40:22 +0200
Subject: [PATCH 13/19] bugfix

---
 ereuse_devicehub/resources/action/views.py | 2 +-
 tests/test_snapshot.py                     | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 19e5ce30..6c5fc77a 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -30,7 +30,7 @@ def save_json(req_json):
     The file need to be saved with one name format with the stamptime and uuid joins
     """
     name_file = "{uuid}_{time}.json".format(uuid=req_json.get('uuid', ''), time=int(time()))
-    path_name = os.path.join(tmp=TMP_SNAPSHOTS, file=name_file)
+    path_name = os.path.join(TMP_SNAPSHOTS, name_file)
 
     if not os.path.isdir(TMP_SNAPSHOTS):
         os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index b3157d38..193604ae 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -491,7 +491,7 @@ def test_save_snapshot_in_file():
 
     snapshot = {'software': '', 'version': '', 'uuid': ''}
     if files:
-        path_snapshot = os.path.join(dir=TMP_SNAPSHOTS, file=files[0])
+        path_snapshot = os.path.join(TMP_SNAPSHOTS, files[0])
         file_snapshot = open(path_snapshot)
         snapshot = json.loads(file_snapshot.read())
         file_snapshot.close()
@@ -514,7 +514,7 @@ def test_backup_snapshot_with_errors(user: UserClient):
 
     files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
     if files:
-        path_snapshot = os.path.join(dir=TMP_SNAPSHOTS, file=files[0])
+        path_snapshot = os.path.join(TMP_SNAPSHOTS, files[0])
         file_snapshot = open(path_snapshot)
         snapshot = json.loads(file_snapshot.read())
         file_snapshot.close()

From 49668a4f4fc7bb20547a5221a8ad354f3fb0e1c9 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Fri, 9 Oct 2020 20:54:12 +0200
Subject: [PATCH 14/19] open files using with statement

---
 ereuse_devicehub/resources/action/views.py |  6 +++---
 tests/test_snapshot.py                     | 12 ++++++------
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 6c5fc77a..58f59627 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -35,9 +35,9 @@ def save_json(req_json):
     if not os.path.isdir(TMP_SNAPSHOTS):
         os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
 
-    snapshot_file = open(path_name, 'w')
-    snapshot_file.write(json.dumps(req_json))
-    snapshot_file.close()
+    with open(path_name, 'w') as snapshot_file:
+        snapshot_file.write(json.dumps(req_json))
+
     return path_name
 
 
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 193604ae..60667da1 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -492,9 +492,9 @@ def test_save_snapshot_in_file():
     snapshot = {'software': '', 'version': '', 'uuid': ''}
     if files:
         path_snapshot = os.path.join(TMP_SNAPSHOTS, files[0])
-        file_snapshot = open(path_snapshot)
-        snapshot = json.loads(file_snapshot.read())
-        file_snapshot.close()
+        with open(path_snapshot) as file_snapshot:
+            snapshot = json.loads(file_snapshot.read())
+
         os.remove(path_snapshot)
 
     assert snapshot['software'] == snapshot_no_hid['software']
@@ -515,9 +515,9 @@ def test_backup_snapshot_with_errors(user: UserClient):
     files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
     if files:
         path_snapshot = os.path.join(TMP_SNAPSHOTS, files[0])
-        file_snapshot = open(path_snapshot)
-        snapshot = json.loads(file_snapshot.read())
-        file_snapshot.close()
+        with open(path_snapshot) as file_snapshot:
+            snapshot = json.loads(file_snapshot.read())
+
         os.remove(path_snapshot)
 
     assert snapshot['software'] == snapshot_no_hid['software']

From c1595aa30589f3ecb620b9b8294dfba0702510a2 Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Tue, 13 Oct 2020 14:44:44 +0200
Subject: [PATCH 15/19] clean imports unused

---
 ereuse_devicehub/resources/action/views.py | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 58f59627..01eab200 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -2,12 +2,10 @@ import os
 import json
 from time import time
 from distutils.version import StrictVersion
-from typing import List
 from uuid import UUID
 
 from flask import current_app as app, request, g
 from sqlalchemy.util import OrderedSet
-from marshmallow.exceptions import ValidationError as mValidationError
 from teal.marshmallow import ValidationError
 from teal.resource import View
 
@@ -15,7 +13,6 @@ from ereuse_devicehub.db import db
 from ereuse_devicehub.resources.action.models import Action, RateComputer, Snapshot, VisualTest, \
     InitTransfer
 from ereuse_devicehub.resources.action.rate.v1_0 import CannotRate
-from ereuse_devicehub.resources.device.models import Component, Computer
 from ereuse_devicehub.resources.enums import SnapshotSoftware, Severity
 from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
 

From ae98d3154c4480e9e3dbfc12c1089ad4addc341d Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Tue, 13 Oct 2020 15:37:21 +0200
Subject: [PATCH 16/19] TMP_SNAPSHOTS defined in config file

---
 ereuse_devicehub/config.py                 |  3 +++
 ereuse_devicehub/resources/action/views.py | 15 ++++++++-------
 tests/conftest.py                          |  1 +
 tests/test_snapshot.py                     | 18 ++++++++++--------
 4 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/ereuse_devicehub/config.py b/ereuse_devicehub/config.py
index 6a176f6e..f7ff436f 100644
--- a/ereuse_devicehub/config.py
+++ b/ereuse_devicehub/config.py
@@ -44,6 +44,9 @@ class DevicehubConfig(Config):
     """The minimum version of ereuse.org workbench that this devicehub
     accepts. we recommend not changing this value.
     """
+
+    TMP_SNAPSHOTS = config('TMP_SNAPSHOTS', '/tmp/snapshots')
+    """This var is for save a snapshots in json format when fail something"""
     API_DOC_CONFIG_TITLE = 'Devicehub'
     API_DOC_CONFIG_VERSION = '0.2'
     API_DOC_CONFIG_COMPONENTS = {
diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index 01eab200..bd146b17 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -1,3 +1,5 @@
+""" This is the view for Snapshots """
+
 import os
 import json
 from time import time
@@ -18,19 +20,17 @@ from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
 
 SUPPORTED_WORKBENCH = StrictVersion('11.0')
 
-TMP_SNAPSHOTS = 'tmp/snapshots'
 
-
-def save_json(req_json):
+def save_json(req_json, tmp_snapshots):
     """
     This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
     The file need to be saved with one name format with the stamptime and uuid joins
     """
     name_file = "{uuid}_{time}.json".format(uuid=req_json.get('uuid', ''), time=int(time()))
-    path_name = os.path.join(TMP_SNAPSHOTS, name_file)
+    path_name = os.path.join(tmp_snapshots, name_file)
 
-    if not os.path.isdir(TMP_SNAPSHOTS):
-        os.system('mkdir -p {}'.format(TMP_SNAPSHOTS))
+    if not os.path.isdir(tmp_snapshots):
+        os.system('mkdir -p {}'.format(tmp_snapshots))
 
     with open(path_name, 'w') as snapshot_file:
         snapshot_file.write(json.dumps(req_json))
@@ -42,7 +42,8 @@ class ActionView(View):
     def post(self):
         """Posts an action."""
         json = request.get_json(validate=False)
-        path_snapshot = save_json(json)
+        tmp_snapshots = app.config['TMP_SNAPSHOTS']
+        path_snapshot = save_json(json, tmp_snapshots)
         if not json or 'type' not in json:
             raise ValidationError('Resource needs a type.')
         # todo there should be a way to better get subclassess resource
diff --git a/tests/conftest.py b/tests/conftest.py
index be01b87f..bdae5797 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -30,6 +30,7 @@ class TestConfig(DevicehubConfig):
     SQLALCHEMY_DATABASE_URI = 'postgresql://dhub:ereuse@localhost/dh_test'
     TESTING = True
     SERVER_NAME = 'localhost'
+    TMP_SNAPSHOTS = '/tmp/snapshots'
 
 
 @pytest.fixture(scope='session')
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 60667da1..e5d88621 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -26,7 +26,7 @@ from ereuse_devicehub.resources.device.sync import MismatchBetweenProperties, \
 from ereuse_devicehub.resources.enums import ComputerChassis, SnapshotSoftware
 from ereuse_devicehub.resources.tag import Tag
 from ereuse_devicehub.resources.user.models import User
-from ereuse_devicehub.resources.action.views import TMP_SNAPSHOTS, save_json
+from ereuse_devicehub.resources.action.views import save_json
 from tests.conftest import file
 
 
@@ -481,17 +481,18 @@ def test_pc_2(user: UserClient):
 
 
 @pytest.mark.mvp
-def test_save_snapshot_in_file():
+def test_save_snapshot_in_file(app: Devicehub):
     """ This test check if works the function save_snapshot_in_file """
+    tmp_snapshots = app.config['TMP_SNAPSHOTS']
     snapshot_no_hid = file('basic.snapshot.nohid')
-    save_json(snapshot_no_hid)
+    save_json(snapshot_no_hid, tmp_snapshots)
 
     uuid = snapshot_no_hid['uuid']
-    files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
+    files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
 
     snapshot = {'software': '', 'version': '', 'uuid': ''}
     if files:
-        path_snapshot = os.path.join(TMP_SNAPSHOTS, files[0])
+        path_snapshot = os.path.join(tmp_snapshots, files[0])
         with open(path_snapshot) as file_snapshot:
             snapshot = json.loads(file_snapshot.read())
 
@@ -503,8 +504,9 @@ def test_save_snapshot_in_file():
 
 
 @pytest.mark.mvp
-def test_backup_snapshot_with_errors(user: UserClient):
+def test_backup_snapshot_with_errors(app: Devicehub, user: UserClient):
     """ This test check if the file snapshot is create when some snapshot is wrong """
+    tmp_snapshots = app.config['TMP_SNAPSHOTS']
     snapshot_no_hid = file('basic.snapshot.badly_formed')
     uuid = snapshot_no_hid['uuid']
 
@@ -512,9 +514,9 @@ def test_backup_snapshot_with_errors(user: UserClient):
     with pytest.raises(KeyError):
         response = user.post(res=Snapshot, data=snapshot_no_hid)
 
-    files = [x for x in os.listdir(TMP_SNAPSHOTS) if uuid in x]
+    files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
     if files:
-        path_snapshot = os.path.join(TMP_SNAPSHOTS, files[0])
+        path_snapshot = os.path.join(tmp_snapshots, files[0])
         with open(path_snapshot) as file_snapshot:
             snapshot = json.loads(file_snapshot.read())
 

From d3ef6cc65d2db15bf13422fe525b3390bd71d2ba Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Tue, 13 Oct 2020 15:59:39 +0200
Subject: [PATCH 17/19] add user to the name file of json and more readable
 date

---
 ereuse_devicehub/resources/action/views.py | 14 ++++++++++----
 tests/test_snapshot.py                     |  4 ++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index bd146b17..bbd1a89f 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -2,7 +2,7 @@
 
 import os
 import json
-from time import time
+from datetime import datetime
 from distutils.version import StrictVersion
 from uuid import UUID
 
@@ -21,12 +21,18 @@ from ereuse_devicehub.resources.user.exceptions import InsufficientPermission
 SUPPORTED_WORKBENCH = StrictVersion('11.0')
 
 
-def save_json(req_json, tmp_snapshots):
+def save_json(req_json, tmp_snapshots, user):
     """
     This function allow save a snapshot in json format un a TMP_SNAPSHOTS directory
     The file need to be saved with one name format with the stamptime and uuid joins
     """
-    name_file = "{uuid}_{time}.json".format(uuid=req_json.get('uuid', ''), time=int(time()))
+    uuid = req_json.get('uuid', '')
+    now = datetime.now()
+    year = now.year
+    month = now.month
+    day = now.day
+
+    name_file = f"{uuid}_{user}_{year}-{month}-{day}.json"
     path_name = os.path.join(tmp_snapshots, name_file)
 
     if not os.path.isdir(tmp_snapshots):
@@ -43,7 +49,7 @@ class ActionView(View):
         """Posts an action."""
         json = request.get_json(validate=False)
         tmp_snapshots = app.config['TMP_SNAPSHOTS']
-        path_snapshot = save_json(json, tmp_snapshots)
+        path_snapshot = save_json(json, tmp_snapshots, g.user.email)
         if not json or 'type' not in json:
             raise ValidationError('Resource needs a type.')
         # todo there should be a way to better get subclassess resource
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index e5d88621..7b328d04 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -481,11 +481,11 @@ def test_pc_2(user: UserClient):
 
 
 @pytest.mark.mvp
-def test_save_snapshot_in_file(app: Devicehub):
+def test_save_snapshot_in_file(app: Devicehub, user: UserClient):
     """ This test check if works the function save_snapshot_in_file """
     tmp_snapshots = app.config['TMP_SNAPSHOTS']
     snapshot_no_hid = file('basic.snapshot.nohid')
-    save_json(snapshot_no_hid, tmp_snapshots)
+    save_json(snapshot_no_hid, tmp_snapshots, user.user['email'])
 
     uuid = snapshot_no_hid['uuid']
     files = [x for x in os.listdir(tmp_snapshots) if uuid in x]

From 150c73779db1b8d4a82ba6ad3fa69aef4d89267f Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Wed, 14 Oct 2020 11:40:33 +0200
Subject: [PATCH 18/19] adding new tests of snapshots

---
 .../failed.snapshot.422.missing-chassis.yaml  | 36 +++++++
 .../failed.snapshot.422.null-chassis.yaml     | 36 +++++++
 ...ed.snapshot.500.missing-cpu-benchmark.yaml | 22 +++++
 ...ed.snapshot.500.missing-hdd-benchmark.yaml | 31 ++++++
 tests/test_snapshot.py                        | 98 +++++++++++++++++++
 5 files changed, 223 insertions(+)
 create mode 100644 tests/files/failed.snapshot.422.missing-chassis.yaml
 create mode 100644 tests/files/failed.snapshot.422.null-chassis.yaml
 create mode 100644 tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml
 create mode 100644 tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml

diff --git a/tests/files/failed.snapshot.422.missing-chassis.yaml b/tests/files/failed.snapshot.422.missing-chassis.yaml
new file mode 100644
index 00000000..1d78da4a
--- /dev/null
+++ b/tests/files/failed.snapshot.422.missing-chassis.yaml
@@ -0,0 +1,36 @@
+type: Snapshot
+uuid: 62b3e393-0c25-42cf-a5fa-ab796fac76dd
+version: 11.0
+software: Workbench
+elapsed: 4
+device: 
+  type: Laptop
+  chassis: Notebook
+  serialNumber: d6s
+  model: d6ml
+  manufacturer: d6mr
+components: 
+  - type: RamModule
+    serialNumber: rm6s
+    model: rm6ml
+    manufacturer: rm6mr
+    speed: 1333
+  - type: Processor
+    serialNumber: p6s
+    model: p6ml
+    manufacturer: p6mr
+    speed: 1.6
+    actions: 
+      - type: BenchmarkProcessor
+        rate: 2410
+        elapsed: 11
+  - type: HardDrive
+    size: 160041.88569599998
+    model: hdd4m
+    manufacturer: hdd4mr
+    serialNumber: hdd4s
+    actions: 
+      - type: BenchmarkDataStorage
+        elapsed: 22
+        writeSpeed: 17.3
+        readSpeed: 41.6
diff --git a/tests/files/failed.snapshot.422.null-chassis.yaml b/tests/files/failed.snapshot.422.null-chassis.yaml
new file mode 100644
index 00000000..0cf56bb7
--- /dev/null
+++ b/tests/files/failed.snapshot.422.null-chassis.yaml
@@ -0,0 +1,36 @@
+type: Snapshot
+uuid: 81e1f340-5aac-4619-931b-d312e4866cb7
+version: 11.0
+software: Workbench
+elapsed: 4
+device: 
+  type: Laptop
+  chassis: null
+  serialNumber: d5s
+  model: d5ml
+  manufacturer: d5mr
+components: 
+  - type: RamModule
+    serialNumber: rm5s
+    model: rm5ml
+    manufacturer: rm5mr
+    speed: 1333
+    type: Processor
+    serialNumber: p5s
+    model: p5ml
+    manufacturer: p5mr
+    speed: 1.6
+    actions: 
+      - type: BenchmarkProcessor
+        rate: 2410
+        elapsed: 11
+    size: 160041.88569599998
+    model: hdd5m
+    type: HardDrive
+    manufacturer: hdd5mr
+    serialNumber: hdd5s
+    actions: 
+      - type: BenchmarkDataStorage
+        elapsed: 22
+        writeSpeed: 17.3
+        readSpeed: 41.6
diff --git a/tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml b/tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml
new file mode 100644
index 00000000..2a5496ae
--- /dev/null
+++ b/tests/files/failed.snapshot.500.missing-cpu-benchmark.yaml
@@ -0,0 +1,22 @@
+type: Snapshot
+uuid: 127fad1c-a3f2-4677-9dab-4a370071a882
+version: 11.0
+software: Workbench
+elapsed: 4
+device: 
+  type: Laptop
+  chassis: Microtower
+  serialNumber: d2s
+  model: d2ml
+  manufacturer: d2mr
+components: 
+  - type: RamModule
+    serialNumber: rm2s
+    model: rm2ml
+    manufacturer: rm2mr
+    speed: 1333
+  - type: Processor
+    serialNumber: p2s
+    model: p2ml
+    manufacturer: p2mr
+    speed: 1.6
diff --git a/tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml b/tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml
new file mode 100644
index 00000000..19269d33
--- /dev/null
+++ b/tests/files/failed.snapshot.500.missing-hdd-benchmark.yaml
@@ -0,0 +1,31 @@
+type: Snapshot
+uuid: 2afa5413-9858-4577-8273-a027a647fed0
+version: 11.0
+software: Workbench
+elapsed: 4
+device: 
+  type: Desktop
+  chassis: Microtower
+  serialNumber: d3s
+  model: d3ml
+  manufacturer: d3mr
+components: 
+  - type: RamModule
+    serialNumber: rm3s
+    model: rm3ml
+    manufacturer: rm3mr
+    speed: 1333
+  - type: Processor
+    serialNumber: p3s
+    model: p3ml
+    manufacturer: p3mr
+    speed: 1.6
+    size: 160041.88569599998
+    model: hdd3m
+    type: HardDrive
+    manufacturer: hdd3mr
+    serialNumber: hdd3s
+    actions: 
+      - type: BenchmarkProcessor
+        rate: 2410
+        elapsed: 11
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 7b328d04..94f9f3e2 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -525,3 +525,101 @@ def test_backup_snapshot_with_errors(app: Devicehub, user: UserClient):
     assert snapshot['software'] == snapshot_no_hid['software']
     assert snapshot['version'] == snapshot_no_hid['version']
     assert snapshot['uuid'] == uuid
+
+
+@pytest.mark.mvp
+def test_snapshot_failed_missing_cpu_benchmark(app: Devicehub, user: UserClient):
+    """ This test check if the file snapshot is create when some snapshot is wrong """
+    tmp_snapshots = app.config['TMP_SNAPSHOTS']
+    snapshot_error = file('failed.snapshot.500.missing-cpu-benchmark')
+    uuid = snapshot_error['uuid']
+
+    snapshot = {'software': '', 'version': '', 'uuid': ''}
+    with pytest.raises(TypeError):
+        user.post(res=Snapshot, data=snapshot_error)
+
+    files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
+    if files:
+        path_snapshot = os.path.join(tmp_snapshots, files[0])
+        with open(path_snapshot) as file_snapshot:
+            snapshot = json.loads(file_snapshot.read())
+
+        os.remove(path_snapshot)
+
+    assert snapshot['software'] == snapshot_error['software']
+    assert snapshot['version'] == snapshot_error['version']
+    assert snapshot['uuid'] == uuid
+
+
+@pytest.mark.mvp
+def test_snapshot_failed_missing_hdd_benchmark(app: Devicehub, user: UserClient):
+    """ This test check if the file snapshot is create when some snapshot is wrong """
+    tmp_snapshots = app.config['TMP_SNAPSHOTS']
+    snapshot_error = file('failed.snapshot.500.missing-hdd-benchmark')
+    uuid = snapshot_error['uuid']
+
+    snapshot = {'software': '', 'version': '', 'uuid': ''}
+    with pytest.raises(TypeError):
+        user.post(res=Snapshot, data=snapshot_error)
+
+    files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
+    if files:
+        path_snapshot = os.path.join(tmp_snapshots, files[0])
+        with open(path_snapshot) as file_snapshot:
+            snapshot = json.loads(file_snapshot.read())
+
+        os.remove(path_snapshot)
+
+    assert snapshot['software'] == snapshot_error['software']
+    assert snapshot['version'] == snapshot_error['version']
+    assert snapshot['uuid'] == uuid
+
+
+@pytest.mark.mvp
+def test_snapshot_failed_null_chassis(app: Devicehub, user: UserClient):
+    """ This test check if the file snapshot is create when some snapshot is wrong """
+    tmp_snapshots = app.config['TMP_SNAPSHOTS']
+    snapshot_error = file('failed.snapshot.422.null-chassis')
+    uuid = snapshot_error['uuid']
+
+    snapshot = {'software': '', 'version': '', 'uuid': ''}
+    # import pdb; pdb.set_trace()
+    with pytest.raises(TypeError):
+        user.post(res=Snapshot, data=snapshot_error)
+
+    files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
+    if files:
+        path_snapshot = os.path.join(tmp_snapshots, files[0])
+        with open(path_snapshot) as file_snapshot:
+            snapshot = json.loads(file_snapshot.read())
+
+        os.remove(path_snapshot)
+
+    assert snapshot['software'] == snapshot_error['software']
+    assert snapshot['version'] == snapshot_error['version']
+    assert snapshot['uuid'] == uuid
+
+
+@pytest.mark.mvp
+def test_snapshot_failed_missing_chassis(app: Devicehub, user: UserClient):
+    """ This test check if the file snapshot is create when some snapshot is wrong """
+    tmp_snapshots = app.config['TMP_SNAPSHOTS']
+    snapshot_error = file('failed.snapshot.422.missing-chassis')
+    uuid = snapshot_error['uuid']
+
+    snapshot = {'software': '', 'version': '', 'uuid': ''}
+    with pytest.raises(TypeError):
+        user.post(res=Snapshot, data=snapshot_error)
+
+    files = [x for x in os.listdir(tmp_snapshots) if uuid in x]
+    if files:
+        path_snapshot = os.path.join(tmp_snapshots, files[0])
+        with open(path_snapshot) as file_snapshot:
+            snapshot = json.loads(file_snapshot.read())
+
+        os.remove(path_snapshot)
+
+    assert snapshot['software'] == snapshot_error['software']
+    assert snapshot['version'] == snapshot_error['version']
+    assert snapshot['uuid'] == uuid
+

From 79b4c738e9b633d88c830c342fcfb5b3e7f2b10c Mon Sep 17 00:00:00 2001
From: Cayo Puigdefabregas <cayo@ribaguifi.com>
Date: Thu, 15 Oct 2020 11:00:11 +0200
Subject: [PATCH 19/19] change the name of the file

---
 ereuse_devicehub/resources/action/views.py | 4 +++-
 tests/test_snapshot.py                     | 1 -
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/ereuse_devicehub/resources/action/views.py b/ereuse_devicehub/resources/action/views.py
index bbd1a89f..689cb942 100644
--- a/ereuse_devicehub/resources/action/views.py
+++ b/ereuse_devicehub/resources/action/views.py
@@ -31,8 +31,10 @@ def save_json(req_json, tmp_snapshots, user):
     year = now.year
     month = now.month
     day = now.day
+    hour = now.hour
+    minutes = now.min
 
-    name_file = f"{uuid}_{user}_{year}-{month}-{day}.json"
+    name_file = f"{year}-{month}-{day}-{hour}-{minutes}_{user}_{uuid}.json"
     path_name = os.path.join(tmp_snapshots, name_file)
 
     if not os.path.isdir(tmp_snapshots):
diff --git a/tests/test_snapshot.py b/tests/test_snapshot.py
index 94f9f3e2..42792c2f 100644
--- a/tests/test_snapshot.py
+++ b/tests/test_snapshot.py
@@ -583,7 +583,6 @@ def test_snapshot_failed_null_chassis(app: Devicehub, user: UserClient):
     uuid = snapshot_error['uuid']
 
     snapshot = {'software': '', 'version': '', 'uuid': ''}
-    # import pdb; pdb.set_trace()
     with pytest.raises(TypeError):
         user.post(res=Snapshot, data=snapshot_error)