Merge lp:~michihenning/storage-framework/metadata-keys into lp:storage-framework/devel

Proposed by Michi Henning
Status: Merged
Approved by: James Henstridge
Approved revision: 92
Merged at revision: 84
Proposed branch: lp:~michihenning/storage-framework/metadata-keys
Merge into: lp:storage-framework/devel
Prerequisite: lp:~michihenning/storage-framework/specify-metadata
Diff against target: 1147 lines (+500/-115)
18 files modified
CMakeLists.txt (+1/-1)
debian/changelog (+1/-0)
demo/provider_test/provider-test.cpp (+5/-5)
include/unity/storage/common.h (+19/-0)
include/unity/storage/internal/metadata_keys.h (+22/-15)
include/unity/storage/qt/Downloader.h (+1/-1)
include/unity/storage/qt/Item.h (+1/-3)
include/unity/storage/qt/MetadataKeys.h.THIS (+37/-0)
include/unity/storage/qt/internal/ItemImpl.h (+1/-2)
src/qt/Item.cpp (+5/-10)
src/qt/client/internal/remote_client/FileImpl.cpp (+2/-2)
src/qt/client/internal/remote_client/ItemImpl.cpp (+3/-3)
src/qt/client/internal/remote_client/validate.cpp (+14/-9)
src/qt/internal/ItemImpl.cpp (+14/-14)
src/qt/internal/validate.cpp (+43/-31)
tests/remote-client-v1/MockProvider.cpp (+5/-5)
tests/remote-client/MockProvider.cpp (+123/-14)
tests/remote-client/remote-client_test.cpp (+203/-0)
To merge this branch: bzr merge lp:~michihenning/storage-framework/metadata-keys
Reviewer Review Type Date Requested Status
unity-api-1-bot continuous-integration Approve
James Henstridge Approve
Review via email: mp+309653@code.launchpad.net

Commit message

Moved metadata key definitions into common.h and move metadata_keys.h to include/unity/storage/internal so both client and server side can see them.
Added commonly supported metadata keys.
Removed free and used space methods (they are metadata now).
No metadata validation for roots because Dropbox can't support that.

Description of the change

Moved metadata key definitions into common.h and move metadata_keys.h to include/unity/storage/internal so both client and server side can see them.
Added commonly supported metadata keys.
Removed free and used space methods (they are metadata now).
No metadata validation for roots because Dropbox can't support that.

To post a comment you must log in.
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:85
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/159/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/919
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/926
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/729/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/729
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/729/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/159/rebuild

review: Approve (continuous-integration)
88. By Michi Henning

Updated changelog. Bumped API version.

89. By Michi Henning

Server-side API version back to 1. Updated changelog accordingly.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:87
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/160/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/920
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/927
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/730/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/730
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/730/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/160/rebuild

review: Approve (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:89
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/161/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/921
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/928
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/731/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/731
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/731/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/161/rebuild

review: Approve (continuous-integration)
90. By Michi Henning

Merged dependent branch.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

FAILED: Continuous integration, rev:90
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/168/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/946/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/953
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/756/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/756
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/756/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/756
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/756/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/756/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/756
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/756/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/756
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/756/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/756/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/756
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/756/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/756
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/756/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/168/rebuild

review: Needs Fixing (continuous-integration)
91. By Michi Henning

Merged dependent branch.

Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:91
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/171/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/949
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/956
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/759/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/759
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/759/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/171/rebuild

review: Approve (continuous-integration)
92. By Michi Henning

Relaxed validation of etag so it applies only to files.

Revision history for this message
James Henstridge (jamesh) wrote :

Looks good.

review: Approve
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote :

PASSED: Continuous integration, rev:92
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/173/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/952
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/959
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/762/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/762
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/762/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-storage-framework-ci/173/rebuild

review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-09-29 11:37:05 +0000
+++ CMakeLists.txt 2016-11-02 06:07:10 +0000
@@ -8,7 +8,7 @@
8project(storage-framework VERSION "0.2" LANGUAGES C CXX)8project(storage-framework VERSION "0.2" LANGUAGES C CXX)
99
10# These variables should be incremented when we wish to create a new10# These variables should be incremented when we wish to create a new
11# source incompatible version of the the library where users of the11# source incompatible version of the library where users of the
12# old API will not compile against the new one. It is not12# old API will not compile against the new one. It is not
13# necessary to increment this for ABI breaks that are source compatible.13# necessary to increment this for ABI breaks that are source compatible.
14set(SF_CLIENT_API_VERSION "2")14set(SF_CLIENT_API_VERSION "2")
1515
=== modified file 'debian/changelog'
--- debian/changelog 2016-09-21 04:41:06 +0000
+++ debian/changelog 2016-11-02 06:07:10 +0000
@@ -2,6 +2,7 @@
22
3 [ Michi Henning ]3 [ Michi Henning ]
4 * Added v2 of the client-side API.4 * Added v2 of the client-side API.
5 * Updated server-side API to tell the provider which metadata to return.
56
6 -- Michi Henning <michi.henning@canonical.com> Wed, 21 Sep 2016 14:36:15 +10007 -- Michi Henning <michi.henning@canonical.com> Wed, 21 Sep 2016 14:36:15 +1000
78
89
=== modified file 'demo/provider_test/provider-test.cpp'
--- demo/provider_test/provider-test.cpp 2016-11-02 06:07:10 +0000
+++ demo/provider_test/provider-test.cpp 2016-11-02 06:07:10 +0000
@@ -16,9 +16,9 @@
16 * Authors: James Henstridge <james.henstridge@canonical.com>16 * Authors: James Henstridge <james.henstridge@canonical.com>
17 */17 */
1818
19#include <unity/storage/common.h>
19#include <unity/storage/provider/DownloadJob.h>20#include <unity/storage/provider/DownloadJob.h>
20#include <unity/storage/provider/Exceptions.h>21#include <unity/storage/provider/Exceptions.h>
21#include <unity/storage/provider/metadata_keys.h>
22#include <unity/storage/provider/ProviderBase.h>22#include <unity/storage/provider/ProviderBase.h>
23#include <unity/storage/provider/Server.h>23#include <unity/storage/provider/Server.h>
24#include <unity/storage/provider/TempfileUploadJob.h>24#include <unity/storage/provider/TempfileUploadJob.h>
@@ -128,7 +128,7 @@
128 {128 {
129 {129 {
130 "child_id", { "root_id" }, "Child", "etag", ItemType::file,130 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
131 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }131 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
132 }132 }
133 };133 };
134 boost::promise<tuple<ItemList,string>> p;134 boost::promise<tuple<ItemList,string>> p;
@@ -154,7 +154,7 @@
154 ItemList children =154 ItemList children =
155 {155 {
156 { "child_id", { "root_id" }, "Child", "etag", ItemType::file,156 { "child_id", { "root_id" }, "Child", "etag", ItemType::file,
157 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } }157 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } }
158 };158 };
159 return make_ready_future<ItemList>(children);159 return make_ready_future<ItemList>(children);
160}160}
@@ -175,7 +175,7 @@
175 Item metadata175 Item metadata
176 {176 {
177 "child_id", { "root_id" }, "Child", "etag", ItemType::file,177 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
178 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }178 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
179 };179 };
180 return make_ready_future<Item>(metadata);180 return make_ready_future<Item>(metadata);
181 }181 }
@@ -289,7 +289,7 @@
289 Item metadata289 Item metadata
290 {290 {
291 "some_id", { "root_id" }, "some_upload", "etag", ItemType::file,291 "some_id", { "root_id" }, "some_upload", "etag", ItemType::file,
292 { { SIZE_IN_BYTES, 10 }, { LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }292 { { metadata::SIZE_IN_BYTES, 10 }, { metadata::LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }
293 };293 };
294 return make_ready_future(metadata);294 return make_ready_future(metadata);
295}295}
296296
=== modified file 'include/unity/storage/common.h'
--- include/unity/storage/common.h 2016-07-12 02:22:05 +0000
+++ include/unity/storage/common.h 2016-11-02 06:07:10 +0000
@@ -37,5 +37,24 @@
37 overwrite,37 overwrite,
38};38};
3939
40namespace metadata
41{
42
43static char constexpr SIZE_IN_BYTES[] = "size_in_bytes"; // int64_t, >= 0
44static char constexpr CREATION_TIME[] = "creation_time"; // String, ISO 8601 format
45static char constexpr LAST_MODIFIED_TIME[] = "last_modified_time"; // String, ISO 8601 format
46static char constexpr CHILD_COUNT[] = "child_count"; // int64_t, >= 0
47static char constexpr DESCRIPTION[] = "description"; // String
48static char constexpr DISPLAY_NAME[] = "display_name"; // String
49static char constexpr FREE_SPACE_BYTES[] = "free_space_bytes"; // int64_t, >= 0
50static char constexpr USED_SPACE_BYTES[] = "used_space_bytes"; // int64_t, >= 0
51static char constexpr CONTENT_TYPE[] = "content_type"; // String
52static char constexpr WRITABLE[] = "writable"; // Bool
53static char constexpr MD5[] = "md5"; // String
54static char constexpr DOWNLOAD_URL[] = "download_url"; // String
55
56static char constexpr ALL[] = "__ALL__";
57
58} // namespace metadata
40} // namespace storage59} // namespace storage
41} // namespace unity60} // namespace unity
4261
=== renamed file 'include/unity/storage/provider/metadata_keys.h' => 'include/unity/storage/internal/metadata_keys.h'
--- include/unity/storage/provider/metadata_keys.h 2016-08-09 02:25:13 +0000
+++ include/unity/storage/internal/metadata_keys.h 2016-11-02 06:07:10 +0000
@@ -18,28 +18,35 @@
1818
19#pragma once19#pragma once
2020
21#include <unity/storage/common.h>
22
21#include <unordered_map>23#include <unordered_map>
2224
23namespace unity25namespace unity
24{26{
25namespace storage27namespace storage
26{28{
27namespace provider29namespace metadata
28{30{
2931
30static char constexpr SIZE_IN_BYTES[] = "size_in_bytes"; // int64_t, >= 032enum class MetadataType { non_zero_pos_int64, iso_8601_date_time, string, boolean };
31static char constexpr CREATION_TIME[] = "creation_time"; // String, ISO 8601 format33
32static char constexpr LAST_MODIFIED_TIME[] = "last_modified_time"; // String, ISO 8601 format34static std::unordered_map<std::string, MetadataType> const known_metadata =
3335{
34enum class MetadataType { int64, iso_8601_date_time };36 { metadata::SIZE_IN_BYTES, MetadataType::non_zero_pos_int64 },
3537 { metadata::CREATION_TIME, MetadataType::iso_8601_date_time },
36static std::unordered_map<std::string, MetadataType> known_metadata =38 { metadata::LAST_MODIFIED_TIME, MetadataType::iso_8601_date_time },
37{39 { metadata::CHILD_COUNT, MetadataType::non_zero_pos_int64 },
38 { SIZE_IN_BYTES, MetadataType::int64 },40 { metadata::DESCRIPTION, MetadataType::string },
39 { CREATION_TIME, MetadataType::iso_8601_date_time },41 { metadata::DISPLAY_NAME, MetadataType::string },
40 { LAST_MODIFIED_TIME, MetadataType::iso_8601_date_time }42 { metadata::FREE_SPACE_BYTES, MetadataType::non_zero_pos_int64 },
43 { metadata::USED_SPACE_BYTES, MetadataType::non_zero_pos_int64 },
44 { metadata::CONTENT_TYPE, MetadataType::string },
45 { metadata::WRITABLE, MetadataType::boolean },
46 { metadata::MD5, MetadataType::string },
47 { metadata::DOWNLOAD_URL, MetadataType::string }
41};48};
4249
43} // namespace provider50} // namespace metadata
44} // namespace storage51} // namespace storage
45} // namespace unity52} // namespace unity
4653
=== modified file 'include/unity/storage/qt/Downloader.h'
--- include/unity/storage/qt/Downloader.h 2016-10-12 05:25:20 +0000
+++ include/unity/storage/qt/Downloader.h 2016-11-02 06:07:10 +0000
@@ -54,7 +54,7 @@
54 bool isValid() const; // Not nice, hides QLocalSocket::isValid()54 bool isValid() const; // Not nice, hides QLocalSocket::isValid()
55 Status status() const;55 Status status() const;
56 StorageError error() const; // Not nice, hides QLocalSocket::error()56 StorageError error() const; // Not nice, hides QLocalSocket::error()
57 Item item() const; // TODO: Should we keep this?57 Item item() const;
5858
59 Q_INVOKABLE void finishDownload();59 Q_INVOKABLE void finishDownload();
60 Q_INVOKABLE void cancel();60 Q_INVOKABLE void cancel();
6161
=== modified file 'include/unity/storage/qt/Item.h'
--- include/unity/storage/qt/Item.h 2016-11-02 06:07:10 +0000
+++ include/unity/storage/qt/Item.h 2016-11-02 06:07:10 +0000
@@ -94,6 +94,7 @@
94 QString etag() const;94 QString etag() const;
95 Type type() const;95 Type type() const;
96 QVariantMap metadata() const;96 QVariantMap metadata() const;
97 qint64 sizeInBytes() const;
97 QDateTime lastModifiedTime() const;98 QDateTime lastModifiedTime() const;
98 QStringList parentIds() const;99 QStringList parentIds() const;
99100
@@ -120,9 +121,6 @@
120 QString const& contentType,121 QString const& contentType,
121 QStringList const& keys = QStringList()) const;122 QStringList const& keys = QStringList()) const;
122123
123 Q_INVOKABLE IntJob* freeSpaceBytes() const;
124 Q_INVOKABLE IntJob* usedSpaceBytes() const;
125
126 bool operator==(Item const&) const;124 bool operator==(Item const&) const;
127 bool operator!=(Item const&) const;125 bool operator!=(Item const&) const;
128 bool operator<(Item const&) const;126 bool operator<(Item const&) const;
129127
=== added file 'include/unity/storage/qt/MetadataKeys.h.THIS'
--- include/unity/storage/qt/MetadataKeys.h.THIS 1970-01-01 00:00:00 +0000
+++ include/unity/storage/qt/MetadataKeys.h.THIS 2016-11-02 06:07:10 +0000
@@ -0,0 +1,37 @@
1/*
2 * Copyright (C) 2016 Canonical Ltd
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors: Michi Henning <michi.henning@canonical.com>
17 */
18
19#pragma once
20
21#include <unity/storage/common.h>
22
23#include <QList>
24#include <QString>
25
26namespace unity
27{
28namespace storage
29{
30namespace qt
31{
32
33static QStringList const ALL_METADATA = { metadata::ALL };
34
35} // namespace qt
36} // namespace storage
37} // namespace unity
038
=== modified file 'include/unity/storage/qt/internal/ItemImpl.h'
--- include/unity/storage/qt/internal/ItemImpl.h 2016-11-02 06:07:10 +0000
+++ include/unity/storage/qt/internal/ItemImpl.h 2016-11-02 06:07:10 +0000
@@ -55,6 +55,7 @@
55 QString etag() const;55 QString etag() const;
56 Item::Type type() const;56 Item::Type type() const;
57 QVariantMap metadata() const;57 QVariantMap metadata() const;
58 qint64 sizeInBytes() const;
58 QDateTime lastModifiedTime() const;59 QDateTime lastModifiedTime() const;
59 QList<QString> parentIds() const;60 QList<QString> parentIds() const;
6061
@@ -73,8 +74,6 @@
73 qint64 sizeInBytes,74 qint64 sizeInBytes,
74 QString const& contentType,75 QString const& contentType,
75 QStringList const& keys) const;76 QStringList const& keys) const;
76 IntJob* freeSpaceBytes() const;
77 IntJob* usedSpaceBytes() const;
7877
79 bool operator==(ItemImpl const&) const;78 bool operator==(ItemImpl const&) const;
80 bool operator!=(ItemImpl const&) const;79 bool operator!=(ItemImpl const&) const;
8180
=== modified file 'src/qt/Item.cpp'
--- src/qt/Item.cpp 2016-11-02 06:07:10 +0000
+++ src/qt/Item.cpp 2016-11-02 06:07:10 +0000
@@ -107,6 +107,11 @@
107 return p_->metadata();107 return p_->metadata();
108}108}
109109
110qint64 Item::sizeInBytes() const
111{
112 return p_->sizeInBytes();
113}
114
110QDateTime Item::lastModifiedTime() const115QDateTime Item::lastModifiedTime() const
111{116{
112 return p_->lastModifiedTime();117 return p_->lastModifiedTime();
@@ -171,16 +176,6 @@
171 return p_->createFile(name, policy, sizeInBytes, contentType, keys);176 return p_->createFile(name, policy, sizeInBytes, contentType, keys);
172}177}
173178
174IntJob* Item::freeSpaceBytes() const
175{
176 return p_->freeSpaceBytes();
177}
178
179IntJob* Item::usedSpaceBytes() const
180{
181 return p_->usedSpaceBytes();
182}
183
184bool Item::operator==(Item const& other) const179bool Item::operator==(Item const& other) const
185{180{
186 return p_->operator==(*other.p_);181 return p_->operator==(*other.p_);
187182
=== modified file 'src/qt/client/internal/remote_client/FileImpl.cpp'
--- src/qt/client/internal/remote_client/FileImpl.cpp 2016-11-02 06:07:10 +0000
+++ src/qt/client/internal/remote_client/FileImpl.cpp 2016-11-02 06:07:10 +0000
@@ -19,7 +19,7 @@
19#include <unity/storage/qt/client/internal/remote_client/FileImpl.h>19#include <unity/storage/qt/client/internal/remote_client/FileImpl.h>
2020
21#include "ProviderInterface.h"21#include "ProviderInterface.h"
22#include <unity/storage/provider/metadata_keys.h>22#include <unity/storage/common.h>
23#include <unity/storage/qt/client/File.h>23#include <unity/storage/qt/client/File.h>
24#include <unity/storage/qt/client/internal/remote_client/Handler.h>24#include <unity/storage/qt/client/internal/remote_client/Handler.h>
25#include <unity/storage/qt/client/internal/remote_client/DownloaderImpl.h>25#include <unity/storage/qt/client/internal/remote_client/DownloaderImpl.h>
@@ -51,7 +51,7 @@
51int64_t FileImpl::size() const51int64_t FileImpl::size() const
52{52{
53 throw_if_destroyed("File::size()");53 throw_if_destroyed("File::size()");
54 return md_.metadata.value(provider::SIZE_IN_BYTES).toLongLong();54 return md_.metadata.value(metadata::SIZE_IN_BYTES).toLongLong();
55}55}
5656
57QFuture<shared_ptr<Uploader>> FileImpl::create_uploader(ConflictPolicy policy, int64_t size)57QFuture<shared_ptr<Uploader>> FileImpl::create_uploader(ConflictPolicy policy, int64_t size)
5858
=== modified file 'src/qt/client/internal/remote_client/ItemImpl.cpp'
--- src/qt/client/internal/remote_client/ItemImpl.cpp 2016-11-02 06:07:10 +0000
+++ src/qt/client/internal/remote_client/ItemImpl.cpp 2016-11-02 06:07:10 +0000
@@ -19,7 +19,7 @@
19#include <unity/storage/qt/client/internal/remote_client/ItemImpl.h>19#include <unity/storage/qt/client/internal/remote_client/ItemImpl.h>
2020
21#include "ProviderInterface.h"21#include "ProviderInterface.h"
22#include <unity/storage/provider/metadata_keys.h>22#include <unity/storage/common.h>
23#include <unity/storage/qt/client/Account.h>23#include <unity/storage/qt/client/Account.h>
24#include <unity/storage/qt/client/internal/remote_client/AccountImpl.h>24#include <unity/storage/qt/client/internal/remote_client/AccountImpl.h>
25#include <unity/storage/qt/client/internal/remote_client/FileImpl.h>25#include <unity/storage/qt/client/internal/remote_client/FileImpl.h>
@@ -72,7 +72,7 @@
72QDateTime ItemImpl::last_modified_time() const72QDateTime ItemImpl::last_modified_time() const
73{73{
74 throw_if_destroyed("Item::last_modified_time()");74 throw_if_destroyed("Item::last_modified_time()");
75 return QDateTime::fromString(md_.metadata.value(provider::LAST_MODIFIED_TIME).toString(), Qt::ISODate);75 return QDateTime::fromString(md_.metadata.value(metadata::LAST_MODIFIED_TIME).toString(), Qt::ISODate);
76}76}
7777
78QFuture<shared_ptr<Item>> ItemImpl::copy(shared_ptr<Folder> const& new_parent, QString const& new_name)78QFuture<shared_ptr<Item>> ItemImpl::copy(shared_ptr<Folder> const& new_parent, QString const& new_name)
@@ -254,7 +254,7 @@
254QDateTime ItemImpl::creation_time() const254QDateTime ItemImpl::creation_time() const
255{255{
256 throw_if_destroyed("Item::creation_time()");256 throw_if_destroyed("Item::creation_time()");
257 return QDateTime::fromString(md_.metadata.value(provider::CREATION_TIME).toString(), Qt::ISODate);257 return QDateTime::fromString(md_.metadata.value(metadata::CREATION_TIME).toString(), Qt::ISODate);
258}258}
259259
260MetadataMap ItemImpl::native_metadata() const260MetadataMap ItemImpl::native_metadata() const
261261
=== modified file 'src/qt/client/internal/remote_client/validate.cpp'
--- src/qt/client/internal/remote_client/validate.cpp 2016-09-28 10:08:40 +0000
+++ src/qt/client/internal/remote_client/validate.cpp 2016-11-02 06:07:10 +0000
@@ -18,7 +18,7 @@
1818
19#include <unity/storage/internal/ItemMetadata.h>19#include <unity/storage/internal/ItemMetadata.h>
2020
21#include <unity/storage/provider/metadata_keys.h>21#include <unity/storage/internal/metadata_keys.h>
22#include <unity/storage/qt/client/Exceptions.h>22#include <unity/storage/qt/client/Exceptions.h>
2323
24#include <QDateTime>24#include <QDateTime>
@@ -48,9 +48,9 @@
4848
49void validate_type_and_value(QString const& prefix,49void validate_type_and_value(QString const& prefix,
50 QMapIterator<QString, QVariant> actual,50 QMapIterator<QString, QVariant> actual,
51 unordered_map<string, provider::MetadataType>::const_iterator known)51 unordered_map<string, metadata::MetadataType>::const_iterator known)
52{52{
53 using namespace unity::storage::provider;53 using namespace unity::storage::metadata;
5454
55 switch (known->second)55 switch (known->second)
56 {56 {
@@ -75,7 +75,7 @@
75 }75 }
76 break;76 break;
77 }77 }
78 case MetadataType::int64:78 case MetadataType::non_zero_pos_int64:
79 {79 {
80 if (actual.value().type() != QVariant::LongLong)80 if (actual.value().type() != QVariant::LongLong)
81 {81 {
@@ -84,6 +84,11 @@
84 }84 }
85 break;85 break;
86 }86 }
87 case MetadataType::string:
88 case MetadataType::boolean:
89 {
90 break;
91 }
87 default:92 default:
88 {93 {
89 abort(); // Impossible. // LCOV_EXCL_LINE94 abort(); // Impossible. // LCOV_EXCL_LINE
@@ -95,7 +100,7 @@
95100
96void validate(QString const& method, ItemMetadata const& md)101void validate(QString const& method, ItemMetadata const& md)
97{102{
98 using namespace unity::storage::provider;103 using namespace unity::storage::metadata;
99104
100 QString prefix = method + ": received invalid metadata from server: ";105 QString prefix = method + ": received invalid metadata from server: ";
101106
@@ -150,13 +155,13 @@
150 // Sanity check metadata to make sure that mandatory fields are present.155 // Sanity check metadata to make sure that mandatory fields are present.
151 if (md.type == ItemType::file)156 if (md.type == ItemType::file)
152 {157 {
153 if (!md.metadata.contains(SIZE_IN_BYTES))158 if (!md.metadata.contains(metadata::SIZE_IN_BYTES))
154 {159 {
155 throw LocalCommsException(prefix + "missing key " + SIZE_IN_BYTES + " in metadata for " + md.item_id);160 throw LocalCommsException(prefix + "missing key " + metadata::SIZE_IN_BYTES + " in metadata for " + md.item_id);
156 }161 }
157 if (!md.metadata.contains(LAST_MODIFIED_TIME))162 if (!md.metadata.contains(metadata::LAST_MODIFIED_TIME))
158 {163 {
159 throw LocalCommsException(prefix + "missing key " + LAST_MODIFIED_TIME + " in metadata for " + md.item_id);164 throw LocalCommsException(prefix + "missing key " + metadata::LAST_MODIFIED_TIME + " in metadata for " + md.item_id);
160 }165 }
161 }166 }
162}167}
163168
=== modified file 'src/qt/internal/ItemImpl.cpp'
--- src/qt/internal/ItemImpl.cpp 2016-11-02 06:07:10 +0000
+++ src/qt/internal/ItemImpl.cpp 2016-11-02 06:07:10 +0000
@@ -19,7 +19,7 @@
19#include <unity/storage/qt/internal/ItemImpl.h>19#include <unity/storage/qt/internal/ItemImpl.h>
2020
21#include "ProviderInterface.h"21#include "ProviderInterface.h"
22#include <unity/storage/provider/metadata_keys.h>22#include <unity/storage/common.h>
23#include <unity/storage/qt/internal/DownloaderImpl.h>23#include <unity/storage/qt/internal/DownloaderImpl.h>
24#include <unity/storage/qt/internal/ItemJobImpl.h>24#include <unity/storage/qt/internal/ItemJobImpl.h>
25#include <unity/storage/qt/internal/ItemListJobImpl.h>25#include <unity/storage/qt/internal/ItemListJobImpl.h>
@@ -96,13 +96,23 @@
9696
97QVariantMap ItemImpl::metadata() const97QVariantMap ItemImpl::metadata() const
98{98{
99 // TODO: Need to agree on metadata representation.99 return is_valid_ ? md_.metadata : QVariantMap();
100 return is_valid_ ? QVariantMap() : QVariantMap();100}
101
102qint64 ItemImpl::sizeInBytes() const
103{
104 if (!is_valid_ || md_.type != ItemType::file)
105 {
106 return 0;
107 }
108 auto variant = md_.metadata.value(metadata::SIZE_IN_BYTES);
109 assert(variant.isValid());
110 return variant.toLongLong();
101}111}
102112
103QDateTime ItemImpl::lastModifiedTime() const113QDateTime ItemImpl::lastModifiedTime() const
104{114{
105 return is_valid_ ? QDateTime::fromString(md_.metadata.value(provider::LAST_MODIFIED_TIME).toString(), Qt::ISODate)115 return is_valid_ ? QDateTime::fromString(md_.metadata.value(metadata::LAST_MODIFIED_TIME).toString(), Qt::ISODate)
106 : QDateTime();116 : QDateTime();
107}117}
108118
@@ -425,16 +435,6 @@
425 return UploaderImpl::make_job(This, method, reply, validate, policy, sizeInBytes);435 return UploaderImpl::make_job(This, method, reply, validate, policy, sizeInBytes);
426}436}
427437
428IntJob* ItemImpl::freeSpaceBytes() const
429{
430 return nullptr; // TODO
431}
432
433IntJob* ItemImpl::usedSpaceBytes() const
434{
435 return nullptr; // TODO
436}
437
438bool ItemImpl::operator==(ItemImpl const& other) const438bool ItemImpl::operator==(ItemImpl const& other) const
439{439{
440 if (is_valid_)440 if (is_valid_)
441441
=== modified file 'src/qt/internal/validate.cpp'
--- src/qt/internal/validate.cpp 2016-09-16 06:25:08 +0000
+++ src/qt/internal/validate.cpp 2016-11-02 06:07:10 +0000
@@ -19,7 +19,7 @@
19#include <unity/storage/qt/internal/validate.h>19#include <unity/storage/qt/internal/validate.h>
2020
21#include <unity/storage/internal/ItemMetadata.h>21#include <unity/storage/internal/ItemMetadata.h>
22#include <unity/storage/provider/metadata_keys.h>22#include <unity/storage/internal/metadata_keys.h>
23#include <unity/storage/qt/internal/StorageErrorImpl.h>23#include <unity/storage/qt/internal/StorageErrorImpl.h>
2424
25#include <QDateTime>25#include <QDateTime>
@@ -45,9 +45,9 @@
4545
46void validate_type_and_value(QString const& prefix,46void validate_type_and_value(QString const& prefix,
47 QMapIterator<QString, QVariant> actual,47 QMapIterator<QString, QVariant> actual,
48 unordered_map<string, provider::MetadataType>::const_iterator known)48 unordered_map<string, metadata::MetadataType>::const_iterator known)
49{49{
50 using namespace unity::storage::provider;50 using namespace unity::storage::metadata;
5151
52 switch (known->second)52 switch (known->second)
53 {53 {
@@ -55,7 +55,7 @@
55 {55 {
56 if (actual.value().type() != QVariant::String)56 if (actual.value().type() != QVariant::String)
57 {57 {
58 QString msg = prefix + actual.key() + ": expected value of type String, but received value of type "58 QString msg = prefix + actual.key() + ": expected value of type QString, but received value of type "
59 + actual.value().typeName();59 + actual.value().typeName();
60 throw StorageErrorImpl::local_comms_error(msg);60 throw StorageErrorImpl::local_comms_error(msg);
61 }61 }
@@ -75,14 +75,26 @@
75 }75 }
76 break;76 break;
77 }77 }
78 case MetadataType::int64:78 case MetadataType::non_zero_pos_int64:
79 {79 {
80 if (actual.value().type() != QVariant::LongLong)80 auto variant = actual.value();
81 {81 if (variant.type() != QVariant::LongLong)
82 QString msg = prefix + actual.key() + ": expected value of type LongLong, but received value of type "82 {
83 + actual.value().typeName();83 QString msg = prefix + actual.key() + ": expected value of type qlonglong, but received value of type "
84 throw StorageErrorImpl::local_comms_error(msg);84 + variant.typeName();
85 }85 throw StorageErrorImpl::local_comms_error(msg);
86 }
87 qint64 val = variant.toLongLong();
88 if (val < 0)
89 {
90 QString msg = prefix + actual.key() + ": expected value >= 0, but received " + QString::number(val);
91 throw StorageErrorImpl::local_comms_error(msg);
92 }
93 break;
94 }
95 case MetadataType::string:
96 case MetadataType::boolean:
97 {
86 break;98 break;
87 }99 }
88 default:100 default:
@@ -96,7 +108,7 @@
96108
97void validate(QString const& method, ItemMetadata const& md)109void validate(QString const& method, ItemMetadata const& md)
98{110{
99 using namespace unity::storage::provider;111 using namespace unity::storage::metadata;
100112
101 QString prefix = method + ": received invalid metadata from provider: ";113 QString prefix = method + ": received invalid metadata from provider: ";
102114
@@ -121,15 +133,18 @@
121 }133 }
122 if (md.type == ItemType::root && !md.parent_ids.isEmpty())134 if (md.type == ItemType::root && !md.parent_ids.isEmpty())
123 {135 {
124 throw StorageErrorImpl::local_comms_error(prefix + "metadata: parent_ids of root must be empty");136 throw StorageErrorImpl::local_comms_error(prefix + "parent_ids of root must be empty");
125 }137 }
126 if (md.name.isEmpty())138 if (md.type != ItemType::root) // Dropbox does not support metadata for roots.
127 {139 {
128 throw StorageErrorImpl::local_comms_error(prefix + "name cannot be empty");140 if (md.name.isEmpty())
129 }141 {
130 if (md.etag.isEmpty())142 throw StorageErrorImpl::local_comms_error(prefix + "name cannot be empty");
131 {143 }
132 throw StorageErrorImpl::local_comms_error(prefix + "etag cannot be empty");144 }
145 if (md.type == ItemType::file && md.etag.isEmpty()) // WebDav doesn't do etag for folders.
146 {
147 throw StorageErrorImpl::local_comms_error(prefix + "etag of a file cannot be empty");
133 }148 }
134149
135 // Sanity check metadata to make sure only known metadata keys appear.150 // Sanity check metadata to make sure only known metadata keys appear.
@@ -140,7 +155,7 @@
140 auto known = known_metadata.find(actual.key().toStdString());155 auto known = known_metadata.find(actual.key().toStdString());
141 if (known == known_metadata.end())156 if (known == known_metadata.end())
142 {157 {
143 qWarning() << prefix << "unknown metadata key:" << actual.key();158 qWarning().noquote().nospace() << prefix << "unknown metadata key: \"" << actual.key() << "\"";
144 }159 }
145 else160 else
146 {161 {
@@ -151,14 +166,11 @@
151 // Sanity check metadata to make sure that mandatory fields are present.166 // Sanity check metadata to make sure that mandatory fields are present.
152 if (md.type == ItemType::file)167 if (md.type == ItemType::file)
153 {168 {
154 if (!md.metadata.contains(SIZE_IN_BYTES))169 if (!md.metadata.contains(metadata::SIZE_IN_BYTES) ||
155 {170 !md.metadata.contains(metadata::LAST_MODIFIED_TIME))
156 QString msg = prefix + "missing key " + SIZE_IN_BYTES + " in metadata for " + md.item_id;171 {
157 throw StorageErrorImpl::local_comms_error(msg);172 QString msg = prefix + "missing key \"" + metadata::SIZE_IN_BYTES + "\" "
158 }173 "in metadata for \"" + md.item_id + "\"";
159 if (!md.metadata.contains(LAST_MODIFIED_TIME))
160 {
161 QString msg = prefix + "missing key " + LAST_MODIFIED_TIME + " in metadata for " + md.item_id;
162 throw StorageErrorImpl::local_comms_error(msg);174 throw StorageErrorImpl::local_comms_error(msg);
163 }175 }
164 }176 }
165177
=== modified file 'tests/remote-client-v1/MockProvider.cpp'
--- tests/remote-client-v1/MockProvider.cpp 2016-11-02 06:07:10 +0000
+++ tests/remote-client-v1/MockProvider.cpp 2016-11-02 06:07:10 +0000
@@ -18,8 +18,8 @@
1818
19#include "MockProvider.h"19#include "MockProvider.h"
2020
21#include <unity/storage/internal/metadata_keys.h>
21#include <unity/storage/provider/Exceptions.h>22#include <unity/storage/provider/Exceptions.h>
22#include <unity/storage/provider/metadata_keys.h>
2323
24#include <boost/thread.hpp>24#include <boost/thread.hpp>
25#include <boost/thread/future.hpp>25#include <boost/thread/future.hpp>
@@ -71,7 +71,7 @@
71 {71 {
72 {72 {
73 "child_id", { "root_id" }, "Child", "etag", ItemType::file,73 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
74 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }74 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
75 }75 }
76 };76 };
77 boost::promise<tuple<ItemList,string>> p;77 boost::promise<tuple<ItemList,string>> p;
@@ -95,7 +95,7 @@
95 ItemList children =95 ItemList children =
96 {96 {
97 { "child_id", { "root_id" }, "Child", "etag", ItemType::file,97 { "child_id", { "root_id" }, "Child", "etag", ItemType::file,
98 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } }98 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } }
99 };99 };
100 return make_ready_future<ItemList>(children);100 return make_ready_future<ItemList>(children);
101}101}
@@ -112,7 +112,7 @@
112 Item metadata112 Item metadata
113 {113 {
114 "child_id", { "root_id" }, "Child", "etag", ItemType::file,114 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
115 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }115 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
116 };116 };
117 return make_ready_future<Item>(metadata);117 return make_ready_future<Item>(metadata);
118 }118 }
@@ -209,7 +209,7 @@
209 Item metadata209 Item metadata
210 {210 {
211 "some_id", { "root_id" }, "some_upload", "etag", ItemType::file,211 "some_id", { "root_id" }, "some_upload", "etag", ItemType::file,
212 { { SIZE_IN_BYTES, 10 }, { LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }212 { { metadata::SIZE_IN_BYTES, 10 }, { metadata::LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }
213 };213 };
214 return make_ready_future(metadata);214 return make_ready_future(metadata);
215}215}
216216
=== modified file 'tests/remote-client/MockProvider.cpp'
--- tests/remote-client/MockProvider.cpp 2016-11-02 06:07:10 +0000
+++ tests/remote-client/MockProvider.cpp 2016-11-02 06:07:10 +0000
@@ -18,8 +18,8 @@
1818
19#include "MockProvider.h"19#include "MockProvider.h"
2020
21#include <unity/storage/internal/metadata_keys.h>
21#include <unity/storage/provider/Exceptions.h>22#include <unity/storage/provider/Exceptions.h>
22#include <unity/storage/provider/metadata_keys.h>
2323
24#include <boost/thread.hpp>24#include <boost/thread.hpp>
25#include <boost/thread/future.hpp>25#include <boost/thread/future.hpp>
@@ -96,7 +96,7 @@
96 {96 {
97 {97 {
98 "child_id", { "root_id" }, "Child", "etag", ItemType::root,98 "child_id", { "root_id" }, "Child", "etag", ItemType::root,
99 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }99 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
100 }100 }
101 };101 };
102 boost::promise<tuple<ItemList,string>> p;102 boost::promise<tuple<ItemList,string>> p;
@@ -114,7 +114,7 @@
114 {114 {
115 {115 {
116 "child_id", { "root_id" }, "Child", "etag", ItemType::file,116 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
117 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }117 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
118 }118 }
119 };119 };
120 }120 }
@@ -125,7 +125,7 @@
125 {125 {
126 {126 {
127 "child2_id", { "root_id" }, "Child2", "etag", ItemType::file,127 "child2_id", { "root_id" }, "Child2", "etag", ItemType::file,
128 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }128 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
129 }129 }
130 };130 };
131 }131 }
@@ -147,7 +147,7 @@
147 {147 {
148 {148 {
149 "child_id", { "root_id" }, "Child", "etag", ItemType::file,149 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
150 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }150 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
151 }151 }
152 };152 };
153 boost::promise<tuple<ItemList,string>> p;153 boost::promise<tuple<ItemList,string>> p;
@@ -171,7 +171,7 @@
171 ItemList children =171 ItemList children =
172 {172 {
173 { "child_id", { "root_id" }, "Child", "etag", ItemType::file,173 { "child_id", { "root_id" }, "Child", "etag", ItemType::file,
174 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } }174 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } } }
175 };175 };
176 return make_ready_future<ItemList>(children);176 return make_ready_future<ItemList>(children);
177}177}
@@ -216,24 +216,133 @@
216 return make_ready_future<Item>(metadata);216 return make_ready_future<Item>(metadata);
217 }217 }
218 }218 }
219 if (cmd_ == "root_with_parent")
220 {
221 Item metadata{"root_id", { "this shouldn't be here" }, "Root", "etag", ItemType::root, {}};
222 return make_ready_future<Item>(metadata);
223 }
219 Item metadata{"root_id", {}, "Root", "etag", ItemType::root, {}};224 Item metadata{"root_id", {}, "Root", "etag", ItemType::root, {}};
220 return make_ready_future<Item>(metadata);225 return make_ready_future<Item>(metadata);
221 }226 }
222 if (item_id == "child_id")227 if (item_id == "child_id")
223 {228 {
229 if (cmd_ == "no_parents")
230 {
231 Item metadata
232 {
233 "child_id", {}, "Child", "etag", ItemType::file,
234 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
235 };
236 return make_ready_future<Item>(metadata);
237 }
238 if (cmd_ == "empty_name")
239 {
240 Item metadata
241 {
242 "child_id", { "root_id" }, "", "etag", ItemType::file,
243 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
244 };
245 return make_ready_future<Item>(metadata);
246 }
247 if (cmd_ == "empty_etag")
248 {
249 Item metadata
250 {
251 "child_id", { "root_id" }, "Child", "", ItemType::file,
252 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
253 };
254 return make_ready_future<Item>(metadata);
255 }
256 if (cmd_ == "unknown_key")
257 {
258 Item metadata
259 {
260 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
261 { { metadata::SIZE_IN_BYTES, 0 },
262 { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" },
263 { metadata::DESCRIPTION, "child test file" }, // For coverage
264 { metadata::WRITABLE, true }, // For coverage
265 { "unknown_key", "" }
266 }
267 };
268 return make_ready_future<Item>(metadata);
269 }
270 if (cmd_ == "missing_key")
271 {
272 Item metadata
273 {
274 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
275 { { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
276 };
277 return make_ready_future<Item>(metadata);
278 }
279 if (cmd_ == "wrong_type_for_time")
280 {
281 Item metadata
282 {
283 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
284 { { metadata::SIZE_IN_BYTES, 10 }, { metadata::LAST_MODIFIED_TIME, true } }
285 };
286 return make_ready_future<Item>(metadata);
287 }
288 if (cmd_ == "bad_parse_for_time")
289 {
290 Item metadata
291 {
292 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
293 { { metadata::SIZE_IN_BYTES, 10 }, { metadata::LAST_MODIFIED_TIME, "xyz" } }
294 };
295 return make_ready_future<Item>(metadata);
296 }
297 if (cmd_ == "missing_timezone")
298 {
299 Item metadata
300 {
301 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
302 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30" } }
303 };
304 return make_ready_future<Item>(metadata);
305 }
306 if (cmd_ == "wrong_type_for_size")
307 {
308 Item metadata
309 {
310 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
311 { { metadata::SIZE_IN_BYTES, "10" }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
312 };
313 return make_ready_future<Item>(metadata);
314 }
315 if (cmd_ == "negative_size")
316 {
317 Item metadata
318 {
319 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
320 { { metadata::SIZE_IN_BYTES, -1 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
321 };
322 return make_ready_future<Item>(metadata);
323 }
324 if (cmd_ == "empty_parent")
325 {
326 Item metadata
327 {
328 "child_id", { "" }, "Child", "etag", ItemType::file,
329 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
330 };
331 return make_ready_future<Item>(metadata);
332 }
224 if (cmd_ == "two_parents" || cmd_ == "two_parents_throw")333 if (cmd_ == "two_parents" || cmd_ == "two_parents_throw")
225 {334 {
226 Item metadata335 Item metadata
227 {336 {
228 "child_id", { "root_id", "child_folder_id" }, "Child", "etag", ItemType::file,337 "child_id", { "root_id", "child_folder_id" }, "Child", "etag", ItemType::file,
229 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }338 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
230 };339 };
231 return make_ready_future<Item>(metadata);340 return make_ready_future<Item>(metadata);
232 }341 }
233 Item metadata342 Item metadata
234 {343 {
235 "child_id", { "root_id" }, "Child", "etag", ItemType::file,344 "child_id", { "root_id" }, "Child", "etag", ItemType::file,
236 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }345 { { metadata::SIZE_IN_BYTES, 10 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
237 };346 };
238 return make_ready_future<Item>(metadata);347 return make_ready_future<Item>(metadata);
239 }348 }
@@ -335,7 +444,7 @@
335 Item metadata444 Item metadata
336 {445 {
337 "root_id", { new_parent_id }, new_name, "etag", ItemType::root,446 "root_id", { new_parent_id }, new_name, "etag", ItemType::root,
338 { { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }447 { { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
339 };448 };
340 return make_ready_future(metadata);449 return make_ready_future(metadata);
341 }450 }
@@ -344,14 +453,14 @@
344 Item metadata453 Item metadata
345 {454 {
346 item_id, { new_parent_id }, new_name, "etag", ItemType::folder,455 item_id, { new_parent_id }, new_name, "etag", ItemType::folder,
347 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }456 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
348 };457 };
349 return make_ready_future(metadata);458 return make_ready_future(metadata);
350 }459 }
351 Item metadata460 Item metadata
352 {461 {
353 item_id, { new_parent_id }, new_name, "etag", ItemType::file,462 item_id, { new_parent_id }, new_name, "etag", ItemType::file,
354 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }463 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
355 };464 };
356 return make_ready_future(metadata);465 return make_ready_future(metadata);
357}466}
@@ -365,14 +474,14 @@
365 Item metadata474 Item metadata
366 {475 {
367 "new_item_id", { new_parent_id }, new_name, "etag", ItemType::folder,476 "new_item_id", { new_parent_id }, new_name, "etag", ItemType::folder,
368 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }477 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
369 };478 };
370 return make_ready_future(metadata);479 return make_ready_future(metadata);
371 }480 }
372 Item metadata481 Item metadata
373 {482 {
374 "new_item_id", { new_parent_id }, new_name, "etag", ItemType::file,483 "new_item_id", { new_parent_id }, new_name, "etag", ItemType::file,
375 { { SIZE_IN_BYTES, 0 }, { LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }484 { { metadata::SIZE_IN_BYTES, 0 }, { metadata::LAST_MODIFIED_TIME, "2007-04-05T14:30Z" } }
376 };485 };
377 return make_ready_future(metadata);486 return make_ready_future(metadata);
378}487}
@@ -416,7 +525,7 @@
416 Item metadata525 Item metadata
417 {526 {
418 "child_id", { "root_id" }, "some_upload", "etag", ItemType::file,527 "child_id", { "root_id" }, "some_upload", "etag", ItemType::file,
419 { { SIZE_IN_BYTES, 10 }, { LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }528 { { metadata::SIZE_IN_BYTES, 10 }, { metadata::LAST_MODIFIED_TIME, "2011-04-05T14:30:10.005Z" } }
420 };529 };
421 return make_ready_future(metadata);530 return make_ready_future(metadata);
422}531}
423532
=== modified file 'tests/remote-client/remote-client_test.cpp'
--- tests/remote-client/remote-client_test.cpp 2016-10-17 13:01:16 +0000
+++ tests/remote-client/remote-client_test.cpp 2016-11-02 06:07:10 +0000
@@ -66,6 +66,7 @@
66class ItemTest : public RemoteClientTest {};66class ItemTest : public RemoteClientTest {};
67class ListTest : public RemoteClientTest {};67class ListTest : public RemoteClientTest {};
68class LookupTest : public RemoteClientTest {};68class LookupTest : public RemoteClientTest {};
69class MetadataTest : public RemoteClientTest {};
69class MoveTest : public RemoteClientTest {};70class MoveTest : public RemoteClientTest {};
70class ParentsTest : public RemoteClientTest {};71class ParentsTest : public RemoteClientTest {};
71class RootsTest : public RemoteClientTest {};72class RootsTest : public RemoteClientTest {};
@@ -345,6 +346,8 @@
345 EXPECT_EQ(AccountsJob::Status::Finished, j->status());346 EXPECT_EQ(AccountsJob::Status::Finished, j->status());
346 EXPECT_EQ(StorageError::Type::NoError, j->error().type());347 EXPECT_EQ(StorageError::Type::NoError, j->error().type());
347348
349 EXPECT_TRUE(runtime_->connection().isConnected()); // Just for coverage.
350
348 auto accounts = j->accounts();351 auto accounts = j->accounts();
349352
350 // We don't check the contents of accounts here because we are using the real online accounts manager353 // We don't check the contents of accounts here because we are using the real online accounts manager
@@ -635,6 +638,203 @@
635 EXPECT_EQ("no_such_id", j->error().itemId());638 EXPECT_EQ("no_such_id", j->error().itemId());
636}639}
637640
641TEST_F(MetadataTest, basic)
642{
643 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider()));
644
645 {
646 Item i;
647 EXPECT_EQ(0, i.metadata().size());
648 }
649
650 {
651 unique_ptr<ItemJob> j(acc_.get("root_id"));
652
653 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
654 spy.wait(SIGNAL_WAIT_TIME);
655
656 EXPECT_EQ(0, j->item().sizeInBytes());
657 EXPECT_EQ(0, j->item().metadata().size());
658 }
659
660 {
661 unique_ptr<ItemJob> j(acc_.get("child_id"));
662
663 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
664 spy.wait(SIGNAL_WAIT_TIME);
665
666 EXPECT_EQ(10, j->item().sizeInBytes());
667 EXPECT_EQ(2, j->item().metadata().size());
668 }
669}
670
671TEST_F(MetadataTest, no_parents)
672{
673 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("no_parents")));
674
675 unique_ptr<ItemJob> j(acc_.get("child_id"));
676
677 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
678 spy.wait(SIGNAL_WAIT_TIME);
679
680 EXPECT_EQ(ItemJob::Status::Error, j->status());
681 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "
682 "file or folder must have at least one parent ID", j->error().errorString());
683}
684
685TEST_F(MetadataTest, empty_parent)
686{
687 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("empty_parent")));
688
689 unique_ptr<ItemJob> j(acc_.get("child_id"));
690
691 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
692 spy.wait(SIGNAL_WAIT_TIME);
693
694 EXPECT_EQ(ItemJob::Status::Error, j->status());
695 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "
696 "parent_id of file or folder cannot be empty", j->error().errorString());
697}
698
699TEST_F(MetadataTest, root_with_parent)
700{
701 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("root_with_parent")));
702
703 unique_ptr<ItemJob> j(acc_.get("root_id"));
704
705 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
706 spy.wait(SIGNAL_WAIT_TIME);
707
708 EXPECT_EQ(ItemJob::Status::Error, j->status());
709 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "
710 "parent_ids of root must be empty", j->error().errorString());
711}
712
713TEST_F(MetadataTest, empty_name)
714{
715 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("empty_name")));
716
717 unique_ptr<ItemJob> j(acc_.get("child_id"));
718
719 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
720 spy.wait(SIGNAL_WAIT_TIME);
721
722 EXPECT_EQ(ItemJob::Status::Error, j->status());
723 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "
724 "name cannot be empty", j->error().errorString());
725}
726
727TEST_F(MetadataTest, empty_etag)
728{
729 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("empty_etag")));
730
731 unique_ptr<ItemJob> j(acc_.get("child_id"));
732
733 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
734 spy.wait(SIGNAL_WAIT_TIME);
735
736 EXPECT_EQ(ItemJob::Status::Error, j->status());
737 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "
738 "etag of a file cannot be empty", j->error().errorString());
739}
740
741TEST_F(MetadataTest, unknown_key)
742{
743 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("unknown_key")));
744
745 unique_ptr<ItemJob> j(acc_.get("child_id"));
746
747 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
748 spy.wait(SIGNAL_WAIT_TIME);
749
750 // We only emit a warning for unknown keys.
751 EXPECT_EQ(ItemJob::Status::Finished, j->status());
752}
753
754TEST_F(MetadataTest, missing_size)
755{
756 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("missing_key")));
757
758 unique_ptr<ItemJob> j(acc_.get("child_id"));
759
760 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
761 spy.wait(SIGNAL_WAIT_TIME);
762
763 EXPECT_EQ(ItemJob::Status::Error, j->status());
764 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: "
765 "missing key \"size_in_bytes\" in metadata for \"child_id\"", j->error().errorString());
766}
767
768TEST_F(MetadataTest, wrong_type_for_time)
769{
770 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("wrong_type_for_time")));
771
772 unique_ptr<ItemJob> j(acc_.get("child_id"));
773
774 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
775 spy.wait(SIGNAL_WAIT_TIME);
776
777 EXPECT_EQ(ItemJob::Status::Error, j->status());
778 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "
779 "expected value of type QString, but received value of type qlonglong", j->error().errorString());
780}
781
782TEST_F(MetadataTest, bad_parse_for_time)
783{
784 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("bad_parse_for_time")));
785
786 unique_ptr<ItemJob> j(acc_.get("child_id"));
787
788 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
789 spy.wait(SIGNAL_WAIT_TIME);
790
791 EXPECT_EQ(ItemJob::Status::Error, j->status());
792 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "
793 "value \"xyz\" does not parse as ISO-8601 date", j->error().errorString());
794}
795
796TEST_F(MetadataTest, missing_timezone)
797{
798 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("missing_timezone")));
799
800 unique_ptr<ItemJob> j(acc_.get("child_id"));
801
802 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
803 spy.wait(SIGNAL_WAIT_TIME);
804
805 EXPECT_EQ(ItemJob::Status::Error, j->status());
806 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: last_modified_time: "
807 "value \"2007-04-05T14:30\" lacks a time zone specification", j->error().errorString());
808}
809
810TEST_F(MetadataTest, wrong_type_for_size)
811{
812 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("wrong_type_for_size")));
813
814 unique_ptr<ItemJob> j(acc_.get("child_id"));
815
816 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
817 spy.wait(SIGNAL_WAIT_TIME);
818
819 EXPECT_EQ(ItemJob::Status::Error, j->status());
820 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: size_in_bytes: "
821 "expected value of type qlonglong, but received value of type QString", j->error().errorString());
822}
823
824TEST_F(MetadataTest, negative_size)
825{
826 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider("negative_size")));
827
828 unique_ptr<ItemJob> j(acc_.get("child_id"));
829
830 QSignalSpy spy(j.get(), &ItemJob::statusChanged);
831 spy.wait(SIGNAL_WAIT_TIME);
832
833 EXPECT_EQ(ItemJob::Status::Error, j->status());
834 EXPECT_EQ("LocalCommsError: Account::get(): received invalid metadata from provider: size_in_bytes: "
835 "expected value >= 0, but received -1", j->error().errorString());
836}
837
638TEST_F(DeleteTest, basic)838TEST_F(DeleteTest, basic)
639{839{
640 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider));840 set_provider(unique_ptr<provider::ProviderBase>(new MockProvider));
@@ -817,6 +1017,8 @@
817 EXPECT_EQ("", i.name());1017 EXPECT_EQ("", i.name());
818 EXPECT_EQ("", i.etag());1018 EXPECT_EQ("", i.etag());
819 EXPECT_EQ(Item::Type::File, i.type());1019 EXPECT_EQ(Item::Type::File, i.type());
1020 EXPECT_EQ(0, i.metadata().size());
1021 EXPECT_EQ(0, i.sizeInBytes());
820 auto mtime = i.lastModifiedTime();1022 auto mtime = i.lastModifiedTime();
821 EXPECT_FALSE(mtime.isValid());1023 EXPECT_FALSE(mtime.isValid());
822 auto pids = i.parentIds();1024 auto pids = i.parentIds();
@@ -834,6 +1036,7 @@
834 EXPECT_TRUE(i.isValid());1036 EXPECT_TRUE(i.isValid());
835 EXPECT_EQ("child_id", i.itemId());1037 EXPECT_EQ("child_id", i.itemId());
836 EXPECT_EQ("Child", i.name());1038 EXPECT_EQ("Child", i.name());
1039 EXPECT_EQ(10, i.sizeInBytes());
837 EXPECT_TRUE(i.account().isValid());1040 EXPECT_TRUE(i.account().isValid());
838 EXPECT_EQ("etag", i.etag());1041 EXPECT_EQ("etag", i.etag());
839 EXPECT_EQ(Item::Type::File, i.type());1042 EXPECT_EQ(Item::Type::File, i.type());

Subscribers

People subscribed via source and target branches

to all changes: