Repository: cernanalysispreservation/cap-client (language: python)

Issue:
files: ask user when overwriting local file on `files download`
currently when file already exists we just overwrite it silently, we should ask user for confirmation


Discussion / hints:
@pamfilos What is the expected result here?

I am assuming that, I have to show a prompt if there exist a `file` with the same [`filename` or `output_filepath`](https://github.com/cernanalysispreservation/cap-client/blob/master/cap_client/api/files_api.py#L73).

I will follow these steps:

- First, Check if there exist a `file` with the same `filename` or `output_filepath`
- If there exist a file, Client will prompt for confirmation(yes/no question) with help of [click.confirm](https://click.palletsprojects.com/en/8.0.x/api/#click.confirm)
- No: Abort the download
- Yes: Overwrite the file

Please let me know wdyt?
Above is perfect. Lets also add an `overwrite/yes-i-know` argument for scripts
okay, What I understand here is add an `overwrite` argument for [`download` files command](https://github.com/cernanalysispreservation/cap-client/blob/master/cap_client/cli/files_cli.py#L103) in the CLI to avoid the Prompt?
Yes. So wee need:
- [ ] If `--yes-i-know` flag option, just overwrite without prompt
- [ ] Else, check if a file exist with the same filename or output_filepath
- [ ] If there exist a file, Client will prompt for confirmation(yes/no question) with help of click.confirm
    - [ ] No: Abort the download
    - [ ] Yes: Overwrite the file

Fix patch:
diff --git a/cap_client/cli/files_cli.py b/cap_client/cli/files_cli.py
index bd0b1a9..5f96e7d 100644
--- a/cap_client/cli/files_cli.py
+++ b/cap_client/cli/files_cli.py
@@ -97,11 +97,27 @@ def upload(api, pid, file, output_filename, yes_i_know):
     type=click.Path(exists=False),
     help='Download file as..',
 )
+@click.option(
+    '--yes-i-know',
+    is_flag=True,
+    default=False,
+    help="Bypasses prompts..Say YES to everything",
+)
 @click.argument('filename')
 @logger
 @pass_api
-def download(api, pid, filename, output_file):
+def download(api, pid, filename, output_file, yes_i_know):
     """Download file uploaded with given deposit."""
+    if not yes_i_know:
+        path = output_file or filename
+        if os.path.exists(path):
+            if not click.confirm(
+                    text="File already exists. Do you want to overwrite?",
+                    default=False,
+                    abort=False,
+                    show_default=True):
+                click.echo("Aborting download of {}".format(output_file or filename))
+                return
     api.download(pid, filename, output_file)
 
     click.echo("File saved as {}".format(output_file or filename))


Test patch:
diff --git a/tests/e2e/cassettes/test_files_upload_and_download.yaml b/tests/e2e/cassettes/test_files_upload_and_download.yaml
new file mode 100644
index 0000000..c37b14a
--- /dev/null
+++ b/tests/e2e/cassettes/test_files_upload_and_download.yaml
@@ -0,0 +1,460 @@
+interactions:
+- request:
+    body: '{"$ana_type": "cms-analysis"}'
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '29'
+      Content-type:
+      - application/json
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: POST
+    uri: https://localhost/api/deposits/
+  response:
+    body:
+      string: '{"access":{"deposit-admin":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]},"deposit-read":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]},"deposit-update":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]}},"created":"2022-01-05T12:53:03.682753+00:00","created_by":{"email":"info@inveniosoftware.org","profile":{}},"experiment":"CMS","files":[],"id":"4f1de5e79ad84a89a352184cdc38749b","is_owner":true,"labels":[],"links":{"bucket":"https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf","clone":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone","discard":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard","disconnect_webhook":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook","edit":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit","files":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files","html":"https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b","permissions":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions","publish":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish","self":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b","upload":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload"},"metadata":{},"revision":0,"schema":{"fullname":"CMS
+        Analysis","name":"cms-analysis","version":"0.0.1"},"status":"draft","type":"deposit","updated":"2022-01-05T12:53:03.682770+00:00"}'
+    headers:
+      Access-Control-Allow-Origin:
+      - '*'
+      Access-Control-Expose-Headers:
+      - Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '1636'
+      Content-Type:
+      - application/json
+      Date:
+      - Wed, 05 Jan 2022 12:53:03 GMT
+      ETag:
+      - '"0"'
+      Last-Modified:
+      - Wed, 05 Jan 2022 12:53:03 GMT
+      Link:
+      - <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b>; rel="self",
+        <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files>; rel="files",
+        <https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b>; rel="html", <https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf>;
+        rel="bucket", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone>;
+        rel="clone", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard>;
+        rel="discard", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook>;
+        rel="disconnect_webhook", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit>;
+        rel="edit", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions>;
+        rel="permissions", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish>;
+        rel="publish", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload>;
+        rel="upload"
+      Retry-After:
+      - '3529'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=15768000
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4998'
+      X-RateLimit-Reset:
+      - '1641390713'
+      location:
+      - https://localhost/deposits/4f1de5e79ad84a89a352184cdc38749b
+    status:
+      code: 201
+      message: CREATED
+- request:
+    body: '{}'
+    headers:
+      Accept:
+      - application/basic+json
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '2'
+      Content-Type:
+      - application/json
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: PUT
+    uri: https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b
+  response:
+    body:
+      string: '{"created":"2022-01-05T12:53:03.682753+00:00","metadata":{},"pid":"4f1de5e79ad84a89a352184cdc38749b","updated":"2022-01-05T12:53:03.989478+00:00"}'
+    headers:
+      Access-Control-Allow-Origin:
+      - '*'
+      Access-Control-Expose-Headers:
+      - Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '146'
+      Content-Type:
+      - application/basic+json
+      Date:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      ETag:
+      - '"1"'
+      Last-Modified:
+      - Wed, 05 Jan 2022 12:53:03 GMT
+      Link:
+      - <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b>; rel="self",
+        <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files>; rel="files",
+        <https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b>; rel="html", <https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf>;
+        rel="bucket", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone>;
+        rel="clone", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard>;
+        rel="discard", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook>;
+        rel="disconnect_webhook", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit>;
+        rel="edit", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions>;
+        rel="permissions", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish>;
+        rel="publish", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload>;
+        rel="upload"
+      Retry-After:
+      - '3512'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=15768000
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4993'
+      X-RateLimit-Reset:
+      - '1641390697'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-type:
+      - application/json
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: GET
+    uri: https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b
+  response:
+    body:
+      string: '{"access":{"deposit-admin":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]},"deposit-read":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]},"deposit-update":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]}},"created":"2022-01-05T12:53:03.682753+00:00","created_by":{"email":"info@inveniosoftware.org","profile":{}},"experiment":"CMS","files":[],"id":"4f1de5e79ad84a89a352184cdc38749b","is_owner":true,"labels":[],"links":{"bucket":"https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf","clone":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone","discard":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard","disconnect_webhook":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook","edit":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit","files":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files","html":"https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b","permissions":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions","publish":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish","self":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b","upload":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload"},"metadata":{},"revision":1,"schema":{"fullname":"CMS
+        Analysis","name":"cms-analysis","version":"0.0.1"},"status":"draft","type":"deposit","updated":"2022-01-05T12:53:03.989478+00:00"}'
+    headers:
+      Access-Control-Allow-Origin:
+      - '*'
+      Access-Control-Expose-Headers:
+      - Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '1636'
+      Content-Type:
+      - application/json
+      Date:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      ETag:
+      - '"1"'
+      Last-Modified:
+      - Wed, 05 Jan 2022 12:53:03 GMT
+      Link:
+      - <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b>; rel="self",
+        <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files>; rel="files",
+        <https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b>; rel="html", <https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf>;
+        rel="bucket", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone>;
+        rel="clone", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard>;
+        rel="discard", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook>;
+        rel="disconnect_webhook", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit>;
+        rel="edit", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions>;
+        rel="permissions", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish>;
+        rel="publish", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload>;
+        rel="upload"
+      Retry-After:
+      - '3512'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=15768000
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4992'
+      X-RateLimit-Reset:
+      - '1641390697'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: !!python/object/new:_io.BytesIO
+      state: !!python/tuple
+      - !!binary |
+        SGVsbG8gd29ybGQ=
+      - 0
+      - null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '11'
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: PUT
+    uri: https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf/file.txt
+  response:
+    body:
+      string: '{"size": 11, "links": {"self": "https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf/file.txt",
+        "version": "https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf/file.txt?versionId=3e941b15-948a-4b48-8e08-a07ad7fc1fb4",
+        "uploads": "https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf/file.txt?uploads"},
+        "delete_marker": false, "mimetype": "text/plain", "is_head": true, "tags":
+        {}, "updated": "2022-01-05T12:53:04.298752+00:00", "created": "2022-01-05T12:53:04.292059+00:00",
+        "key": "file.txt", "version_id": "3e941b15-948a-4b48-8e08-a07ad7fc1fb4", "checksum":
+        "md5:3e25960a79dbc69b674cd4ec67a72c62"}'
+    headers:
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '637'
+      Content-Security-Policy:
+      - 'default-src ''self'' data: ''unsafe-inline'' ''unsafe-eval''; img-src ''self''
+        data: ''unsafe-inline'' ''unsafe-eval'''
+      Content-Type:
+      - application/json
+      Date:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      ETag:
+      - '"md5:3e25960a79dbc69b674cd4ec67a72c62"'
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Retry-After:
+      - '3529'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=31556926; includeSubDomains
+      - max-age=15768000
+      X-Content-Security-Policy:
+      - 'default-src ''self'' data: ''unsafe-inline'' ''unsafe-eval''; img-src ''self''
+        data: ''unsafe-inline'' ''unsafe-eval'''
+      X-Content-Type-Options:
+      - nosniff
+      X-Frame-Options:
+      - sameorigin
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4997'
+      X-RateLimit-Reset:
+      - '1641390714'
+      X-XSS-Protection:
+      - 1; mode=block
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-type:
+      - application/json
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: GET
+    uri: https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b
+  response:
+    body:
+      string: '{"access":{"deposit-admin":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]},"deposit-read":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]},"deposit-update":{"roles":[],"users":[{"email":"info@inveniosoftware.org","profile":{}}]}},"created":"2022-01-05T12:53:03.682753+00:00","created_by":{"email":"info@inveniosoftware.org","profile":{}},"experiment":"CMS","files":[{"bucket":"2d444b03-65c6-4662-b91a-c25fc24e78bf","checksum":"md5:3e25960a79dbc69b674cd4ec67a72c62","key":"file.txt","size":11,"version_id":"3e941b15-948a-4b48-8e08-a07ad7fc1fb4"}],"id":"4f1de5e79ad84a89a352184cdc38749b","is_owner":true,"labels":[],"links":{"bucket":"https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf","clone":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone","discard":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard","disconnect_webhook":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook","edit":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit","files":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files","html":"https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b","permissions":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions","publish":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish","self":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b","upload":"https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload"},"metadata":{},"revision":1,"schema":{"fullname":"CMS
+        Analysis","name":"cms-analysis","version":"0.0.1"},"status":"draft","type":"deposit","updated":"2022-01-05T12:53:03.989478+00:00"}'
+    headers:
+      Access-Control-Allow-Origin:
+      - '*'
+      Access-Control-Expose-Headers:
+      - Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '1814'
+      Content-Type:
+      - application/json
+      Date:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      ETag:
+      - '"1"'
+      Last-Modified:
+      - Wed, 05 Jan 2022 12:53:03 GMT
+      Link:
+      - <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b>; rel="self",
+        <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/files>; rel="files",
+        <https://localhost/drafts/4f1de5e79ad84a89a352184cdc38749b>; rel="html", <https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf>;
+        rel="bucket", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/clone>;
+        rel="clone", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/discard>;
+        rel="discard", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/disconnect_webhook>;
+        rel="disconnect_webhook", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/edit>;
+        rel="edit", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/permissions>;
+        rel="permissions", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/publish>;
+        rel="publish", <https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b/actions/upload>;
+        rel="upload"
+      Retry-After:
+      - '3511'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=15768000
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4991'
+      X-RateLimit-Reset:
+      - '1641390696'
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: GET
+    uri: https://localhost/api/files/2d444b03-65c6-4662-b91a-c25fc24e78bf/file.txt
+  response:
+    body:
+      string: Hello world
+    headers:
+      Accept-Ranges:
+      - none
+      Connection:
+      - keep-alive
+      Content-Disposition:
+      - inline
+      Content-Length:
+      - '11'
+      Content-MD5:
+      - 3e25960a79dbc69b674cd4ec67a72c62
+      Content-Security-Policy:
+      - 'default-src ''self'' data: ''unsafe-inline'' ''unsafe-eval''; img-src ''self''
+        data: ''unsafe-inline'' ''unsafe-eval'''
+      Content-Type:
+      - text/plain; charset=utf-8
+      Date:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      ETag:
+      - '"md5:3e25960a79dbc69b674cd4ec67a72c62"'
+      Last-Modified:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      Referrer-Policy:
+      - strict-origin-when-cross-origin
+      Retry-After:
+      - '3529'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=31556926; includeSubDomains
+      - max-age=15768000
+      X-Content-Security-Policy:
+      - 'default-src ''self'' data: ''unsafe-inline'' ''unsafe-eval''; img-src ''self''
+        data: ''unsafe-inline'' ''unsafe-eval'''
+      X-Content-Type-Options:
+      - nosniff
+      X-Download-Options:
+      - noopen
+      X-Frame-Options:
+      - sameorigin
+      X-Permitted-Cross-Domain-Policies:
+      - none
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4996'
+      X-RateLimit-Reset:
+      - '1641390714'
+      X-XSS-Protection:
+      - 1; mode=block
+    status:
+      code: 200
+      message: OK
+- request:
+    body: null
+    headers:
+      Accept:
+      - '*/*'
+      Accept-Encoding:
+      - gzip, deflate
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '0'
+      Content-type:
+      - application/json
+      User-Agent:
+      - python-requests/2.26.0
+      authorization:
+      - DUMMY
+    method: DELETE
+    uri: https://localhost/api/deposits/4f1de5e79ad84a89a352184cdc38749b
+  response:
+    body:
+      string: ''
+    headers:
+      Access-Control-Allow-Origin:
+      - '*'
+      Access-Control-Expose-Headers:
+      - Content-Type, ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
+      Connection:
+      - keep-alive
+      Content-Length:
+      - '0'
+      Content-Type:
+      - text/html; charset=utf-8
+      Date:
+      - Wed, 05 Jan 2022 12:53:04 GMT
+      Retry-After:
+      - '3511'
+      Server:
+      - nginx/1.21.4
+      Strict-Transport-Security:
+      - max-age=15768000
+      X-RateLimit-Limit:
+      - '5000'
+      X-RateLimit-Remaining:
+      - '4990'
+      X-RateLimit-Reset:
+      - '1641390696'
+    status:
+      code: 204
+      message: NO CONTENT
+version: 1
diff --git a/tests/e2e/test_files_cli.py b/tests/e2e/test_files_cli.py
new file mode 100644
index 0000000..1958953
--- /dev/null
+++ b/tests/e2e/test_files_cli.py
@@ -0,0 +1,56 @@
+# -*- coding: utf-8 -*-
+#
+# This file is part of CERN Analysis Preservation Framework.
+# Copyright (C) 2022 CERN.
+#
+# CERN Analysis Preservation Framework is free software; you can redistribute
+# it and/or modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# CERN Analysis Preservation Framework is distributed in the hope that it will
+# be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with CERN Analysis Preservation Framework; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307, USA.
+#
+# In applying this license, CERN does not
+# waive the privileges and immunities granted to it by virtue of its status
+# as an Intergovernmental Organization or submit itself to any jurisdiction.
+
+import os
+import json
+import pytest
+
+
+@pytest.mark.vcr
+def test_files_upload_and_download(cli_run, user_tokens, vcr_config):
+    # apply the token
+    user_tokens('info@inveniosoftware.org')
+
+    # create a draft analysis
+    create_draft_res = cli_run('analysis create --json {} --type cms-analysis')
+
+    # get the pid of the draft
+    draft_pid = json.loads(create_draft_res.output).get('pid')
+
+    with open('file.txt', 'wb') as fp:
+        fp.write(b'Hello world')
+
+    # test `files upload`
+    res_upload = cli_run(f'files upload -p {draft_pid} file.txt')
+    assert res_upload.exit_code == 0
+    assert res_upload.stripped_output == 'File uploaded successfully.'
+    os.remove('file.txt')
+
+    # test `files download`
+    res_download = cli_run(f'files download -p {draft_pid} file.txt')
+    assert res_download.exit_code == 0
+    assert res_download.stripped_output == 'File saved as file.txt'
+
+    # delete the draft
+    cli_run(f'analysis delete -p {draft_pid}')