Merge lp:~dobey/unity-scope-click/clicksnap into lp:unity-scope-click

Proposed by dobey
Status: Rejected
Rejected by: dobey
Proposed branch: lp:~dobey/unity-scope-click/clicksnap
Merge into: lp:unity-scope-click
Prerequisite: lp:~dobey/unity-scope-click/ual-apps
Diff against target: 1900 lines (+682/-390)
23 files modified
bin/CMakeLists.txt (+4/-1)
bin/install-helper (+9/-2)
bin/install-snap (+73/-0)
debian/control (+6/-3)
libclickscope/click/configuration.cpp (+13/-3)
libclickscope/click/configuration.h (+1/-0)
libclickscope/click/download-manager.cpp (+53/-83)
libclickscope/click/download-manager.h (+4/-8)
libclickscope/click/index.cpp (+60/-6)
libclickscope/click/index.h (+11/-2)
libclickscope/click/package.cpp (+4/-0)
libclickscope/click/package.h (+4/-0)
libclickscope/click/preview.cpp (+16/-5)
libclickscope/click/webclient.cpp (+26/-17)
libclickscope/click/webclient.h (+2/-0)
libclickscope/tests/mock_webclient.h (+11/-7)
libclickscope/tests/test_bootstrap.cpp (+2/-2)
libclickscope/tests/test_download_manager.cpp (+155/-127)
libclickscope/tests/test_index.cpp (+157/-91)
libclickscope/tests/test_pay.cpp (+13/-13)
libclickscope/tests/test_preview.cpp (+2/-2)
libclickscope/tests/test_reviews.cpp (+16/-16)
scope/clickstore/store-query.cpp (+40/-2)
To merge this branch: bzr merge lp:~dobey/unity-scope-click/clicksnap
Reviewer Review Type Date Requested Status
unity-api-1-bot continuous-integration Approve
Charles Kerr (community) Approve
Review via email: mp+303974@code.launchpad.net

This proposal supersedes a proposal from 2016-08-24.

Commit message

Initial support in store scope for searching and installing snaps.

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

PASSED: Continuous integration, rev:496
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/86/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/470
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/476
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/381
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/381
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/381
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/311/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/311
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/311/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/86/rebuild

review: Approve (continuous-integration)
Revision history for this message
unity-api-1-bot (unity-api-1-bot) wrote : Posted in a previous version of this proposal

PASSED: Continuous integration, rev:497
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/88/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/474
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/480
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/385
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/315/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/315
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/315/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/88/rebuild

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

PASSED: Continuous integration, rev:497
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/89/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/489
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/495
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/400
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/400
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/400
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/330/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/330
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/330/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/89/rebuild

review: Approve (continuous-integration)
498. By dobey

Update dependencies to allow either snaps or clicks to be supported.

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

FAILED: Continuous integration, rev:498
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/91/
Executed test runs:
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build/493/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/499
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=vivid+overlay/404
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=xenial+overlay/404
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-1-sourcepkg/release=yakkety/404
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/334/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/334/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/334/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/334/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/334/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/334/artifact/output/*zip*/output.zip
    FAILURE: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/334/console
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/334/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/334
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/334/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/91/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Charles Kerr (charlesk) wrote :

Review pt. 1 of 2, comments inline. About to be in transit and will finish review afterwards

review: Needs Information
Revision history for this message
Charles Kerr (charlesk) wrote :

Review pt. 2 of 2 inline. No showstoppers but a few more questions/comments

review: Needs Information
Revision history for this message
Charles Kerr (charlesk) :
499. By dobey

Merge up chagnes from ual-apps.

500. By dobey

Collapse snapd.socket check to simplify function.

501. By dobey

Remove the extra check for downloads.size > 1, as it shouldn't happen.

502. By dobey

Some cleanup in download-manager.cpp per code review.

503. By dobey

Fixes to index.cpp per code review.

504. By dobey

Break up mock responseForReply per code review.

505. By dobey

Refactor index tests perh code review.

506. By dobey

Use const auto in for loops.

Revision history for this message
dobey (dobey) wrote :

On Sat, 2016-09-03 at 01:11 +0000, Charles Kerr wrote:
> (optional) when a function reaches two bool arguments it's a
> candidate for an options bitfield a la GBusNameOwnerFlags

This is somewhat temporary. When we only support snaps, this will get
factored back out, as we won't need to know if something is a snap or
not at that point, since we'll only support snaps.

> I get that this isn't a red or green line, but out of curiosity,
> what's the rationale for calling details_callback() twice like this?
> So that showing the rest of the information won't block on the
> screenshot download?

I think maybe you were tired when you read this? Those are two
different branches of an if statement. :)

> 1. Each of the new tests looks at something unique, but they also
> look at get_architecture and get_available_framemworks in exactly the
> same way without any apparent benefit from the duplication. Maybe
> that should be moved into its own test; or if it's necessary for each
> of these tests, at least extracted into a fixture method that all of
> these can call

Refactored this into two different fixture classes.

> (needinfo) Is this correct? Shouldn't we be checking pkg.name or
> pkg.alias for empty() instead of pkg.snap_id?

Did it this way because we specifically only want to use alias for
snaps, and I think there isn't quite any guarantee that alias will
always we empty for clicks. However, this is also quite temporary, as
when we only support snaps, we'll only use what is appropriate for
that, and not worry about supporting clicks.

> (needinfo) Capturing 'this' in lambdas-inside-lambdas is always
> dicey. Are we certain that the lifetime of 'this' is safe s.t. it can
> be used this way?

I think this is fine here, as the outer call returns a pointer which we
store in this's private data, and which when destroyed aborts the
network requests, should prevent the callbacks being called, as the
requests get aborted. There is theoretically a possible race here, but
this will also be reduced back to single level when we stop supporting
clicks.

Revision history for this message
dobey (dobey) wrote :

On Fri, 2016-09-02 at 21:21 +0000, Charles Kerr wrote:
> (bikeshed) IMO "return (retval == 0) && ((sb.st_mode & S_IFMT) ==
> S_IFSOCK));" is more readable as it boils the function down to a
> single exit point

Thought it might be useful to do something with errno at some point
when I wrote this, but it's not really important here, so changed this
to the simpler return anyway. :)

> (question) when writing code like this I've been favoring
> qPrintable(str) for terseness over QString::fromStdString(str). Other
> than code readability, is there any real difference / advantage to
> choosing one over the other?

I was formerly using str.c_str() in most places, but fromStdString()
seems more explicit, and it's consistent with the rest of the code here
for now. Ideally I think we should probably do something else to make
this more readable (and switch to the simple logging hack I wrote a
while back, at some point).

> (minor) QList.size() isn't guaranteed to be constant complexity and
> we call downloadss.size() a few lines above too, suggest a const
> temporary to hold the size
>
> (needinfo) How is this reached??

Just removed this extra if() here, as it should indeed never be
reached, and simpler code is better. This also reduces the calls to
size() to a single call.

> (needinfo / needs fixing) Isn't this a dangling pointer here as
> toUtf8() goes out-of-scope at the end of this line?
>

Not entirely sure of the semantics here and if it would be a dangling
pointer, but after looking at the code, it seems like using
toStdString() would be better anyway, so I've changed this code, and
the bit below it to use that instead.

> (bikeshed) c++11's nested list-initialization lets you do this really
> cleanly, something like

Right, but we're not initializing from an empty map here. We're taking
a const input, and need to insert additional items into it. So we need
to copy the old list, then add the new items. I don't think we can do
that with the braces initializer.

> Seems like 'description' deserves a line in an error log somewhere

Not sure why it wasn't, but fixed here and in the other method this was
copied from.

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

PASSED: Continuous integration, rev:506
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/101/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/600
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/606
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/430/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/430
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/430/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/101/rebuild

review: Approve (continuous-integration)
507. By dobey

Want const references for the for loops here.

Revision history for this message
Charles Kerr (charlesk) wrote :

> I think maybe you were tired when you read this? Those are two different branches of an if statement. :)

d'oh!

Thanks for the rest of the fixes & answers. Overall, a nice branch

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

PASSED: Continuous integration, rev:507
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/102/
Executed test runs:
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build/601
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-0-fetch/607
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=vivid+overlay/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=xenial+overlay/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=amd64,release=yakkety/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=vivid+overlay/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=xenial+overlay/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=armhf,release=yakkety/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=vivid+overlay/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=xenial+overlay/431/artifact/output/*zip*/output.zip
    SUCCESS: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/431
        deb: https://jenkins.canonical.com/unity-api-1/job/build-2-binpkg/arch=i386,release=yakkety/431/artifact/output/*zip*/output.zip

Click here to trigger a rebuild:
https://jenkins.canonical.com/unity-api-1/job/lp-unity-scope-click-ci/102/rebuild

review: Approve (continuous-integration)
508. By dobey

New script to download snap assertions and perform install

509. By dobey

Fix the snap script to do the right thing.
Add necessary dependencies for the script.

510. By dobey

Check that filename argument is non-empty before continuing.

511. By dobey

Check if name is alias instead of using snap_id to determine if snap.

512. By dobey

If frameworks list is empty send "none" instead of empty header.

513. By dobey

Use a bash function instead of variable for wget, to avoid weird escaping.

Unmerged revisions

513. By dobey

Use a bash function instead of variable for wget, to avoid weird escaping.

512. By dobey

If frameworks list is empty send "none" instead of empty header.

511. By dobey

Check if name is alias instead of using snap_id to determine if snap.

510. By dobey

Check that filename argument is non-empty before continuing.

509. By dobey

Fix the snap script to do the right thing.
Add necessary dependencies for the script.

508. By dobey

New script to download snap assertions and perform install

507. By dobey

Want const references for the for loops here.

506. By dobey

Use const auto in for loops.

505. By dobey

Refactor index tests perh code review.

504. By dobey

Break up mock responseForReply per code review.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/CMakeLists.txt'
--- bin/CMakeLists.txt 2014-08-14 14:59:57 +0000
+++ bin/CMakeLists.txt 2016-09-21 14:55:05 +0000
@@ -1,1 +1,4 @@
1install(PROGRAMS install-helper enable-purchases DESTINATION lib/unity-scope-click/)1install(
2 PROGRAMS install-helper install-snap enable-purchases
3 DESTINATION lib/unity-scope-click/
4)
25
=== modified file 'bin/install-helper'
--- bin/install-helper 2014-06-20 05:09:01 +0000
+++ bin/install-helper 2016-09-21 14:55:05 +0000
@@ -1,6 +1,6 @@
1#!/bin/bash1#!/bin/bash
2#2#
3# Copyright (C) 2014 Canonical Ltd.3# Copyright (C) 2014-2016 Canonical Ltd.
4# 4#
5# This program is free software: you can redistribute it and/or modify it5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published6# under the terms of the GNU General Public License version 3, as published
@@ -47,7 +47,14 @@
4747
48function install-package {48function install-package {
49 FILE_NAME="$1"49 FILE_NAME="$1"
50 pkcon -p install-local "$FILE_NAME"50 FILE_TYPE="${FILE_NAME##*.}"
51 if [ ${FILE_TYPE} = "click" ]; then
52 pkcon -p install-local "${FILE_NAME}"
53 else
54 SCRIPT_PATH=`dirname $0`
55 SNAP_SCRIPT="${SCRIPT_PATH}/install-snap"
56 pkexec ${SNAP_SCRIPT} "${FILE_NAME}"
57 fi
51}58}
5259
53function app_id-from-package_name {60function app_id-from-package_name {
5461
=== added file 'bin/install-snap'
--- bin/install-snap 1970-01-01 00:00:00 +0000
+++ bin/install-snap 2016-09-21 14:55:05 +0000
@@ -0,0 +1,73 @@
1#!/bin/bash
2#
3# Copyright (C) 2016 Canonical Ltd.
4#
5# This program is free software: you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 3, as published
7# by the Free Software Foundation.
8#
9# This program is distributed in the hope that it will be useful, but
10# WITHOUT ANY WARRANTY; without even the implied warranties of
11# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12# PURPOSE. See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along
15# with this program. If not, see <http://www.gnu.org/licenses/>.
16#
17# In addition, as a special exception, the copyright holders give
18# permission to link the code of portions of this program with the
19# OpenSSL library under certain conditions as described in each
20# individual source file, and distribute linked combinations
21# including the two.
22# You must obey the GNU General Public License in all respects
23# for all of the code used other than OpenSSL. If you modify
24# file(s) with this exception, you may extend this exception to your
25# version of the file(s), but you are not obligated to do so. If you
26# do not wish to do so, delete this exception statement from your
27# version. If you delete this exception statement from all source
28# files in the program, then also delete it here.
29#
30
31set -ex
32
33if [ -z "$1" ]; then
34 echo "usage: install-snap <filename.snap>"
35 exit -10
36fi
37
38SNAP_FILE_NAME="$1"
39SNAP_FILE=$(basename ${SNAP_FILE_NAME})
40SNAP_REVID=${SNAP_FILE%%.*}
41SNAP_ID=${SNAP_REVID%%_*}
42SNAP_REV=${SNAP_REVID##*_}
43
44# We have to get not just the 384 hash, but a "snap-digest" for the snap.
45# This is a base64-encoded binary hex of the sha3 384 hash
46SNAP_SHA3SUM=$(sha3sum -a 384 ${SNAP_FILE_NAME} | cut -d ' ' -f1)
47SNAP_B64SHA=$(echo ${SNAP_SHA3SUM} | python3 -c 'import sys, binascii, base64; print(base64.urlsafe_b64encode(binascii.a2b_hex((sys.stdin.readline().strip().encode("ASCII")))).decode("ASCII").rstrip("="))')
48
49
50# Need to get the assertions to add to snapd
51ASSERTIONS_BASE_URL="https://assertions.ubuntu.com/v1/assertions"
52function download {
53 wget --header "Accept: application/x.ubuntu.assertion" -O - $1 > $2
54}
55
56# The '16' is hard-coded here for series. By the time it changes again, we
57# should have switched to using snapd for everything anyway.
58download "${ASSERTIONS_BASE_URL}/snap-declaration/16/${SNAP_ID}" "${SNAP_FILE_NAME}.snap-declaration"
59download "${ASSERTIONS_BASE_URL}/snap-revision/${SNAP_B64SHA}" "${SNAP_FILE_NAME}.snap-revision"
60
61# We have to get the publisher-id to get the account assertion for install
62AUTHOR_ID=$(grep "publisher-id:" ${SNAP_FILE_NAME}.snap-declaration | cut -d ' ' -f2)
63download "${ASSERTIONS_BASE_URL}/account/${AUTHOR_ID}" "${SNAP_FILE_NAME}.account"
64
65# snap exits with error if assertion already exists, so must ignore errors :-/
66snap ack "${SNAP_FILE_NAME}.account" || true
67snap ack "${SNAP_FILE_NAME}.snap-declaration" || true
68snap ack "${SNAP_FILE_NAME}.snap-revision" || true
69
70# Delete the assertions files after importing them
71rm -f "${SNAP_FILE_NAME}.*"
72
73snap install ${SNAP_FILE_NAME}
074
=== modified file 'debian/control'
--- debian/control 2016-09-21 14:55:05 +0000
+++ debian/control 2016-09-21 14:55:05 +0000
@@ -40,16 +40,19 @@
40Package: unity-scope-click40Package: unity-scope-click
41Architecture: armhf arm64 i386 amd6441Architecture: armhf arm64 i386 amd64
42Depends: account-plugin-ubuntuone,42Depends: account-plugin-ubuntuone,
43 grep,
44 libdigest-sha3-perl,
43 libglib2.0-bin,45 libglib2.0-bin,
44 libsqlite3-0 (>= 3.8.5),46 libsqlite3-0 (>= 3.8.5),
45 packagekit,47 snapd | packagekit,
46 packagekit-tools,48 snapd | packagekit-tools,
47 pay-service,49 pay-service,
48 ubuntu-app-launch-tools,50 ubuntu-app-launch-tools,
49 ubuntu-download-manager,51 ubuntu-download-manager,
50 ubuntu-sdk-libs,52 snapd | ubuntu-sdk-libs,
51 unity-scope-click-departmentsdb (= ${binary:Version}),53 unity-scope-click-departmentsdb (= ${binary:Version}),
52 upstart,54 upstart,
55 wget,
53 ${misc:Depends},56 ${misc:Depends},
54 ${shlibs:Depends},57 ${shlibs:Depends},
55Breaks: unity (<< 7.0),58Breaks: unity (<< 7.0),
5659
=== modified file 'libclickscope/click/configuration.cpp'
--- libclickscope/click/configuration.cpp 2016-02-19 03:35:43 +0000
+++ libclickscope/click/configuration.cpp 2016-09-21 14:55:05 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014-2015 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -27,6 +27,8 @@
27 * files in the program, then also delete it here.27 * files in the program, then also delete it here.
28 */28 */
2929
30#include "configuration.h"
31
30#include <string>32#include <string>
31#include <vector>33#include <vector>
3234
@@ -43,8 +45,9 @@
4345
44#include <boost/algorithm/string.hpp>46#include <boost/algorithm/string.hpp>
45#include <boost/algorithm/string/replace.hpp>47#include <boost/algorithm/string/replace.hpp>
4648#include <sys/stat.h>
47#include "configuration.h"49#include <sys/types.h>
50#include <unistd.h>
4851
49namespace click {52namespace click {
5053
@@ -121,6 +124,13 @@
121 return arch;124 return arch;
122}125}
123126
127bool Configuration::is_snapd_running() const
128{
129 struct stat sb;
130 int retval = stat("/run/snapd.socket", &sb);
131 return retval == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK;
132}
133
124bool Configuration::get_purchases_enabled()134bool Configuration::get_purchases_enabled()
125{135{
126 const char* env_value = std::getenv(PURCHASES_ENVVAR);136 const char* env_value = std::getenv(PURCHASES_ENVVAR);
127137
=== modified file 'libclickscope/click/configuration.h'
--- libclickscope/click/configuration.h 2016-09-21 14:55:05 +0000
+++ libclickscope/click/configuration.h 2016-09-21 14:55:05 +0000
@@ -54,6 +54,7 @@
5454
55 virtual std::vector<std::string> get_available_frameworks();55 virtual std::vector<std::string> get_available_frameworks();
56 virtual std::string get_architecture();56 virtual std::string get_architecture();
57 virtual bool is_snapd_running() const;
57 static bool get_purchases_enabled();58 static bool get_purchases_enabled();
58 static std::string get_currency(const std::string& fallback = CURRENCY_DEFAULT);59 static std::string get_currency(const std::string& fallback = CURRENCY_DEFAULT);
5960
6061
=== modified file 'libclickscope/click/download-manager.cpp'
--- libclickscope/click/download-manager.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/click/download-manager.cpp 2016-09-21 14:55:05 +0000
@@ -57,12 +57,6 @@
5757
58static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";58static const QString DOWNLOAD_MANAGER_SHA512 = "sha512";
5959
60const QByteArray& CLICK_TOKEN_HEADER()
61{
62 static const QByteArray result("X-Click-Token");
63 return result;
64}
65
66DownloadManager::DownloadManager(const QSharedPointer<click::web::Client>& client,60DownloadManager::DownloadManager(const QSharedPointer<click::web::Client>& client,
67 const QSharedPointer<udm::Manager>& manager) :61 const QSharedPointer<udm::Manager>& manager) :
68 client(client),62 client(client),
@@ -86,11 +80,8 @@
86 if (downloads.size() > 0) {80 if (downloads.size() > 0) {
87 auto download = downloads.at(0);81 auto download = downloads.at(0);
88 object_path = download->id().toStdString();82 object_path = download->id().toStdString();
89 }83 qDebug() << "Found object path" << QString::fromStdString(object_path)
90 qDebug() << "Found object path" << QString::fromStdString(object_path)84 << "for package" << QString::fromStdString(package_name);
91 << "for package" << QString::fromStdString(package_name);
92 if (downloads.size() > 1) {
93 qWarning() << "More than one download with the same object path";
94 }85 }
95 callback(object_path);86 callback(object_path);
96 }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){87 }, [callback, package_name](const QString& /*key*/, const QString& /*value*/, DownloadsList* /*downloads_list*/){
@@ -100,78 +91,57 @@
100 });91 });
101}92}
10293
103click::web::Cancellable DownloadManager::start(const std::string& url,94void DownloadManager::start(const std::string& url,
104 const std::string& download_sha512,95 const std::string& download_sha512,
105 const std::string& package_name,96 const std::string& package_name,
106 const std::function<void (std::string, Error)>& callback)97 const std::function<void (std::string, Error)>& callback)
107{98{
108 QSharedPointer<click::web::Response> response = client->call99 auto signature = client->signUrl(url, "GET");
109 (url, "HEAD", true);100
110101 QVariantMap metadata;
111 QObject::connect(response.data(), &click::web::Response::finished,102
112 [this, callback, url, download_sha512, package_name,103 auto commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str());
113 response](QString) {104 metadata[DOWNLOAD_COMMAND_KEY] = commandline;
114 auto status = response->get_status_code();105 metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str();
115 if (status == 200) {106 metadata["package_name"] = package_name.c_str();
116 auto clickToken = response->get_header(CLICK_TOKEN_HEADER().data());107
117 qDebug() << "Received click token:" << clickToken.c_str();108 QMap<QString, QString> headers;
118 QVariantMap metadata;109 headers[click::web::AUTHORIZATION_HEADER.c_str()] = signature.c_str();
119110
120 QVariant commandline = QVariant(QStringList() << DOWNLOAD_COMMAND << "$file" << package_name.c_str());111 udm::DownloadStruct downloadStruct(url.c_str(),
121 metadata[DOWNLOAD_COMMAND_KEY] = commandline;112 download_sha512.c_str(),
122 metadata[DOWNLOAD_APP_ID_KEY] = package_name.c_str();113 DOWNLOAD_MANAGER_SHA512,
123 metadata["package_name"] = package_name.c_str();114 metadata,
124115 headers);
125 QMap<QString, QString> headers;116
126 headers[CLICK_TOKEN_HEADER()] = clickToken.c_str();117 dm->createDownload(downloadStruct,
127118 [callback](Download* download) {
128 udm::DownloadStruct downloadStruct(url.c_str(),119 if (download != nullptr) {
129 download_sha512.c_str(),120 if (download->isError()) {
130 DOWNLOAD_MANAGER_SHA512,121 auto errorstr = download->error()->errorString();
131 metadata,122 auto error = errorstr.toStdString();
132 headers);123 qDebug() << "Received error from ubuntu-download-manager:" << errorstr;
133124 callback(error, Error::DownloadInstallError);
134 dm->createDownload(downloadStruct,125 } else {
135 [callback](Download* download) {126 download->start();
136 if (download->isError()) {127 callback(download->id().toStdString(),
137 auto error = download->error()->errorString().toUtf8().data();128 Error::NoError);
138 qDebug() << "Received error from ubuntu-download-manager:" << error;129 }
139 callback(error, Error::DownloadInstallError);130 } else {
140 } else {131 callback("Received nullptr for download.",
141 download->start();132 Error::DownloadInstallError);
142 callback(download->id().toUtf8().data(), Error::NoError);133 }
143 }134 },
144 },135 [callback](Download* download) {
145 [callback](Download* download) {136 if (download != nullptr) {
146 callback(download->error()->errorString().toUtf8().data(),137 auto errorstr = download->error()->errorString();
147 Error::DownloadInstallError);138 auto error = errorstr.toStdString();
148 });139 callback(error, Error::DownloadInstallError);
149 } else {140 } else {
150 std::string error{"Unhandled HTTP response code: "};141 callback("Received nullptr for download.",
151 error += status;142 Error::DownloadInstallError);
152 callback(error, Error::DownloadInstallError);143 }
153 }144 });
154 });
155 QObject::connect(response.data(), &click::web::Response::error,
156 [this, callback, package_name](QString error, int error_code) {
157 qWarning() << QStringLiteral("Network error (%1) fetching click token for:").arg(error_code) << package_name.c_str();
158 switch(error_code) {
159 case 401:
160 case 403:
161 client->invalidateCredentials();
162 callback(error.toUtf8().data(), Error::CredentialsError);
163 break;
164 default:
165 callback(error.toUtf8().data(), Error::DownloadInstallError);
166 }
167 });
168
169 return click::web::Cancellable(response);
170}
171
172void DownloadManager::setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService)
173{
174 sso = credentialsService;
175}145}
176146
177} // namespace click147} // namespace click
178148
=== modified file 'libclickscope/click/download-manager.h'
--- libclickscope/click/download-manager.h 2016-02-26 18:51:22 +0000
+++ libclickscope/click/download-manager.h 2016-09-21 14:55:05 +0000
@@ -68,18 +68,14 @@
6868
69 virtual void get_progress(const std::string& package_name,69 virtual void get_progress(const std::string& package_name,
70 const std::function<void (std::string)>& callback);70 const std::function<void (std::string)>& callback);
71 virtual click::web::Cancellable start(const std::string& url,71 virtual void start(const std::string& url,
72 const std::string& download_sha512,72 const std::string& download_sha512,
73 const std::string& package_name,73 const std::string& package_name,
74 const std::function<void (std::string,74 const std::function<void (std::string, Error)>& callback);
75 Error)>& callback);
76
77 virtual void setCredentialsService(const QSharedPointer<click::CredentialsService>& credentialsService);
7875
79protected:76protected:
80 QSharedPointer<click::web::Client> client;77 QSharedPointer<click::web::Client> client;
81 QSharedPointer<Ubuntu::DownloadManager::Manager> dm;78 QSharedPointer<Ubuntu::DownloadManager::Manager> dm;
82 QSharedPointer<click::CredentialsService> sso;
83};79};
8480
85}81}
8682
=== modified file 'libclickscope/click/index.cpp'
--- libclickscope/click/index.cpp 2016-04-26 10:56:47 +0000
+++ libclickscope/click/index.cpp 2016-09-21 14:55:05 +0000
@@ -112,8 +112,13 @@
112std::map<std::string, std::string> Index::build_headers()112std::map<std::string, std::string> Index::build_headers()
113{113{
114 std::stringstream frameworks;114 std::stringstream frameworks;
115 for (auto f: configuration->get_available_frameworks()) {115 const auto frameworklist = configuration->get_available_frameworks();
116 frameworks << "," << f;116 if (frameworklist.empty()) {
117 frameworks << "none";
118 } else {
119 for (const auto& f: frameworklist) {
120 frameworks << "," << f;
121 }
117 }122 }
118123
119 return std::map<std::string, std::string> {124 return std::map<std::string, std::string> {
@@ -123,6 +128,15 @@
123 };128 };
124}129}
125130
131std::map<std::string, std::string> Index::add_snap_headers(const std::map<std::string, std::string>& headers) const
132{
133 std::map<std::string, std::string> new_headers{headers};
134 new_headers["X-Ubuntu-Series"] = "16"; // Need to get from snapd
135 new_headers["X-Ubuntu-Slots"] = "unity8"; // Only want unity8-using snaps
136
137 return new_headers;
138}
139
126std::pair<Packages, Packages> Index::package_lists_from_json(const std::string& json)140std::pair<Packages, Packages> Index::package_lists_from_json(const std::string& json)
127{141{
128 Json::Reader reader;142 Json::Reader reader;
@@ -147,6 +161,35 @@
147 return std::pair<Packages, Packages>(pl, recommends);161 return std::pair<Packages, Packages>(pl, recommends);
148}162}
149163
164click::web::Cancellable Index::search_snaps(const std::string& query,
165 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
166 bool force_cache)
167{
168 click::web::CallParams params;
169 auto built_query = build_index_query(query, "" /* No dept for snaps */);
170 params.add(click::QUERY_ARGNAME, built_query.c_str());
171
172 auto headers = add_snap_headers(build_headers());
173
174 QSharedPointer<click::web::Response> response
175 (client->call(get_base_url() + click::SNAP_SEARCH_PATH,
176 "GET", true, headers, "", params, force_cache));
177
178 QObject::connect(response.data(), &click::web::Response::finished, [=](QString reply) {
179 auto package_lists = package_lists_from_json(reply.toUtf8().constData());
180 callback(package_lists.first, package_lists.second);
181 });
182 QObject::connect(response.data(), &click::web::Response::error, [=](QString description) {
183 qWarning() << "No packages found due to network error:" << description;
184 click::Packages pl;
185 click::Packages recommends;
186 qDebug() << "calling callback";
187 callback(pl, recommends);
188 qDebug() << " ...Done!";
189 });
190 return click::web::Cancellable(response);
191}
192
150click::web::Cancellable Index::search (const std::string& query, const std::string& department,193click::web::Cancellable Index::search (const std::string& query, const std::string& department,
151 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,194 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
152 bool force_cache)195 bool force_cache)
@@ -162,8 +205,8 @@
162 package_lists = package_lists_from_json(reply.toUtf8().constData());205 package_lists = package_lists_from_json(reply.toUtf8().constData());
163 callback(package_lists.first, package_lists.second);206 callback(package_lists.first, package_lists.second);
164 });207 });
165 QObject::connect(response.data(), &click::web::Response::error, [=](QString /*description*/) {208 QObject::connect(response.data(), &click::web::Response::error, [=](QString description) {
166 qDebug() << "No packages found due to network error";209 qWarning() << "No packages found due to network error:" << description;
167 click::Packages pl;210 click::Packages pl;
168 click::Packages recommends;211 click::Packages recommends;
169 qDebug() << "calling callback";212 qDebug() << "calling callback";
@@ -215,10 +258,21 @@
215 return click::web::Cancellable(response);258 return click::web::Cancellable(response);
216}259}
217260
218click::web::Cancellable Index::get_details (const std::string& package_name, std::function<void(PackageDetails, click::Index::Error)> callback, bool force_cache)261click::web::Cancellable Index::get_details (const std::string& package_name,
262 std::function<void(PackageDetails,
263 click::Index::Error)> callback,
264 bool is_snap,
265 bool force_cache)
219{266{
267 std::string details_path{click::DETAILS_PATH};
268 auto headers = build_headers();
269 if (is_snap) {
270 details_path = click::SNAP_DETAILS_PATH;
271 headers = add_snap_headers(headers);
272 }
220 QSharedPointer<click::web::Response> response = client->call273 QSharedPointer<click::web::Response> response = client->call
221 (get_base_url() + click::DETAILS_PATH + package_name,274 (get_base_url() + details_path + package_name,
275 "GET", true, headers, "",
222 click::web::CallParams(),276 click::web::CallParams(),
223 force_cache);277 force_cache);
224 qDebug() << "getting details for" << package_name.c_str();278 qDebug() << "getting details for" << package_name.c_str();
225279
=== modified file 'libclickscope/click/index.h'
--- libclickscope/click/index.h 2016-04-26 10:56:47 +0000
+++ libclickscope/click/index.h 2016-09-21 14:55:05 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -49,11 +49,13 @@
49const std::string SEARCH_BASE_URL_ENVVAR = "U1_SEARCH_BASE_URL";49const std::string SEARCH_BASE_URL_ENVVAR = "U1_SEARCH_BASE_URL";
50const std::string SEARCH_BASE_URL = "https://search.apps.ubuntu.com/";50const std::string SEARCH_BASE_URL = "https://search.apps.ubuntu.com/";
51const std::string SEARCH_PATH = "api/v1/search";51const std::string SEARCH_PATH = "api/v1/search";
52const std::string SNAP_SEARCH_PATH = "api/v1/snaps/search";
52const std::string BOOTSTRAP_PATH = "api/v1";53const std::string BOOTSTRAP_PATH = "api/v1";
53const std::string SUPPORTED_FRAMEWORKS = "framework:ubuntu-sdk-13.10";54const std::string SUPPORTED_FRAMEWORKS = "framework:ubuntu-sdk-13.10";
54const std::string QUERY_ARGNAME = "q";55const std::string QUERY_ARGNAME = "q";
55const std::string ARCHITECTURE = "architecture:";56const std::string ARCHITECTURE = "architecture:";
56const std::string DETAILS_PATH = "api/v1/package/";57const std::string DETAILS_PATH = "api/v1/package/";
58const std::string SNAP_DETAILS_PATH = "api/v1/snaps/details/";
57const std::string CURRENCY_HEADER = "X-Suggested-Currency";59const std::string CURRENCY_HEADER = "X-Suggested-Currency";
5860
59class PackageManager61class PackageManager
@@ -72,6 +74,7 @@
72 std::string m_suggested_currency;74 std::string m_suggested_currency;
73 virtual std::string build_index_query(const std::string& query, const std::string& department);75 virtual std::string build_index_query(const std::string& query, const std::string& department);
74 virtual std::map<std::string, std::string> build_headers();76 virtual std::map<std::string, std::string> build_headers();
77 virtual std::map<std::string, std::string> add_snap_headers(const std::map<std::string, std::string>& headers) const;
7578
76public:79public:
77 enum class Error {NoError, CredentialsError, NetworkError};80 enum class Error {NoError, CredentialsError, NetworkError};
@@ -79,9 +82,15 @@
79 Index(const QSharedPointer<click::web::Client>& client,82 Index(const QSharedPointer<click::web::Client>& client,
80 const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration()));83 const QSharedPointer<Configuration> configuration=QSharedPointer<Configuration>(new Configuration()));
81 virtual std::pair<Packages, Packages> package_lists_from_json(const std::string& json);84 virtual std::pair<Packages, Packages> package_lists_from_json(const std::string& json);
85 virtual click::web::Cancellable search_snaps(const std::string& query,
86 std::function<void(click::Packages search_results, click::Packages recommendations)> callback,
87 bool force_cache = false);
82 virtual click::web::Cancellable search (const std::string& query, const std::string& department, std::function<void(Packages, Packages)> callback, bool88 virtual click::web::Cancellable search (const std::string& query, const std::string& department, std::function<void(Packages, Packages)> callback, bool
83 force_cache = false);89 force_cache = false);
84 virtual click::web::Cancellable get_details(const std::string& package_name, std::function<void(PackageDetails, Error)> callback, bool force_cache = false);90 virtual click::web::Cancellable get_details(const std::string& package_name,
91 std::function<void(PackageDetails, Error)> callback,
92 bool is_snap = false,
93 bool force_cache = false);
85 virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback, bool force_cache = false);94 virtual click::web::Cancellable bootstrap(std::function<void(const DepartmentList&, const HighlightList&, Error, int)> callback, bool force_cache = false);
86 virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error, int)>95 virtual click::web::Cancellable departments(const std::string& department_href, std::function<void(const DepartmentList&, const HighlightList&, Error, int)>
87 callback, bool force_cache = false);96 callback, bool force_cache = false);
8897
=== modified file 'libclickscope/click/package.cpp'
--- libclickscope/click/package.cpp 2015-11-24 18:23:23 +0000
+++ libclickscope/click/package.cpp 2016-09-21 14:55:05 +0000
@@ -95,6 +95,10 @@
95 p.publisher = item[Package::JsonKeys::publisher].asString();95 p.publisher = item[Package::JsonKeys::publisher].asString();
96 p.rating = item[Package::JsonKeys::rating].asDouble();96 p.rating = item[Package::JsonKeys::rating].asDouble();
97 p.version = item[Package::JsonKeys::version].asString();97 p.version = item[Package::JsonKeys::version].asString();
98
99 p.snap_id = item[Package::JsonKeys::snap_id].asString();
100 p.alias = item[Package::JsonKeys::alias].asString();
101
98 return p;102 return p;
99}103}
100104
101105
=== modified file 'libclickscope/click/package.h'
--- libclickscope/click/package.h 2015-11-24 18:23:23 +0000
+++ libclickscope/click/package.h 2016-09-21 14:55:05 +0000
@@ -64,6 +64,8 @@
64 constexpr static const char* publisher{"publisher"};64 constexpr static const char* publisher{"publisher"};
65 constexpr static const char* rating{"ratings_average"};65 constexpr static const char* rating{"ratings_average"};
66 constexpr static const char* version{"version"};66 constexpr static const char* version{"version"};
67 constexpr static const char* snap_id{"snap_id"};
68 constexpr static const char* alias{"alias"};
6769
68 // NOTE: The "price" field is deprecated in favor of "prices"70 // NOTE: The "price" field is deprecated in favor of "prices"
69 constexpr static const char* prices{"prices"};71 constexpr static const char* prices{"prices"};
@@ -107,6 +109,8 @@
107 void matches (std::string query, std::function<bool> callback);109 void matches (std::string query, std::function<bool> callback);
108 std::string content;110 std::string content;
109 std::map<std::string, double> prices;111 std::map<std::string, double> prices;
112 std::string snap_id;
113 std::string alias;
110114
111 struct hash_name {115 struct hash_name {
112 public :116 public :
113117
=== modified file 'libclickscope/click/preview.cpp'
--- libclickscope/click/preview.cpp 2016-09-21 14:55:05 +0000
+++ libclickscope/click/preview.cpp 2016-09-21 14:55:05 +0000
@@ -442,7 +442,11 @@
442 // and code using it does not need to worry about threading/event loop topics.442 // and code using it does not need to worry about threading/event loop topics.
443 run_under_qt([this, details_callback, reviews_callback, app_name, force_cache]()443 run_under_qt([this, details_callback, reviews_callback, app_name, force_cache]()
444 {444 {
445 index_operation = index->get_details(app_name, [this, app_name, details_callback, reviews_callback, force_cache](PackageDetails details, click::Index::Error error){445 index_operation = index->get_details(app_name,
446 [this, app_name,
447 details_callback,
448 reviews_callback,
449 force_cache](PackageDetails details, click::Index::Error error){
446 if(error == click::Index::Error::NoError) {450 if(error == click::Index::Error::NoError) {
447 qDebug() << "Got details:" << app_name.c_str();451 qDebug() << "Got details:" << app_name.c_str();
448 details_callback(details);452 details_callback(details);
@@ -455,10 +459,17 @@
455 details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]);459 details.main_screenshot_url = get_string_maybe_null(result["main_screenshot"]);
456 details_callback(details);460 details_callback(details);
457 }461 }
458 reviews_operation = reviews->fetch_reviews(app_name,462 // FIXME: No RNR support for v2 snaps yet, so avoid the
459 reviews_callback,463 // network hit if we're showing a snap preview
460 force_cache);464 if (app_name.rfind(".") != std::string::npos) {
461 }, force_cache);465 reviews_operation = reviews->fetch_reviews(app_name,
466 reviews_callback,
467 force_cache);
468 } else {
469 reviews_callback(click::ReviewList{},
470 click::Reviews::Error::NoError);
471 }
472 }, app_name.rfind(".") == std::string::npos, force_cache);
462 });473 });
463 }474 }
464}475}
465476
=== modified file 'libclickscope/click/webclient.cpp'
--- libclickscope/click/webclient.cpp 2016-05-25 16:19:51 +0000
+++ libclickscope/click/webclient.cpp 2016-09-21 14:55:05 +0000
@@ -78,6 +78,26 @@
78{78{
79}79}
8080
81std::string click::web::Client::signUrl(const std::string& url,
82 const std::string& method)
83{
84 QString signature;
85
86 if (impl->sso.isNull()) {
87 qCritical() << "Unable to sign request without SSO object.";
88 } else {
89 auto token = impl->sso->getToken();
90 if (token.isValid()) {
91 signature = token.signUrl(QString::fromStdString(url),
92 QString::fromStdString(method));
93 qDebug() << "Signed URL:" << QString::fromStdString(url);
94 } else {
95 qWarning() << "Signing requested but returned token is invalid.";
96 }
97 }
98 return signature.toStdString();
99}
100
81QSharedPointer<click::web::Response> click::web::Client::call(101QSharedPointer<click::web::Response> click::web::Client::call(
82 const std::string& iri,102 const std::string& iri,
83 const click::web::CallParams& params,103 const click::web::CallParams& params,
@@ -137,25 +157,14 @@
137 auto deviceId = Configuration().get_device_id();157 auto deviceId = Configuration().get_device_id();
138 request->setRawHeader(DEVICE_ID_HEADER.c_str(), deviceId.data());158 request->setRawHeader(DEVICE_ID_HEADER.c_str(), deviceId.data());
139159
140 if (sign && !impl->sso.isNull()) {160 if (sign) {
141 auto token = impl->sso->getToken();161 auto auth_header = signUrl(url.toString().toStdString(), method);
142 if (token.isValid()) {162 if (!auth_header.empty())
143 QString auth_header = token.signUrl(url.toString(),163 request->setRawHeader(AUTHORIZATION_HEADER.c_str(),
144 method.c_str());164 auth_header.c_str());
145 qDebug() << "Signed URL:" << request->url().toString();
146 request->setRawHeader(AUTHORIZATION_HEADER.c_str(), auth_header.toUtf8());
147 } else {
148 qWarning() << "Signing reuested but returned token is invalid.";
149 }
150
151 doConnect();
152 } else {
153 if (sign && impl->sso.isNull()) {
154 qCritical() << "Unable to sign request without SSO object.";
155 }
156 doConnect();
157 }165 }
158166
167 doConnect();
159168
160 return responsePtr;169 return responsePtr;
161}170}
162171
=== modified file 'libclickscope/click/webclient.h'
--- libclickscope/click/webclient.h 2016-05-25 16:19:51 +0000
+++ libclickscope/click/webclient.h 2016-09-21 14:55:05 +0000
@@ -115,6 +115,8 @@
115 Client(const QSharedPointer<click::network::AccessManager>& networkAccessManager);115 Client(const QSharedPointer<click::network::AccessManager>& networkAccessManager);
116 virtual ~Client();116 virtual ~Client();
117117
118 virtual std::string signUrl(const std::string& url,
119 const std::string& method);
118 virtual QSharedPointer<Response> call(120 virtual QSharedPointer<Response> call(
119 const std::string& iri,121 const std::string& iri,
120 const CallParams& params = CallParams(), bool force_cache = false);122 const CallParams& params = CallParams(), bool force_cache = false);
121123
=== modified file 'libclickscope/tests/mock_webclient.h'
--- libclickscope/tests/mock_webclient.h 2016-05-25 16:19:51 +0000
+++ libclickscope/tests/mock_webclient.h 2016-09-21 14:55:05 +0000
@@ -61,13 +61,6 @@
61 Mock instance;61 Mock instance;
62};62};
6363
64QSharedPointer<click::web::Response> responseForReply(const QSharedPointer<click::network::Reply>& reply)
65{
66 auto response = QSharedPointer<click::web::Response>(new click::web::Response(QSharedPointer<QNetworkRequest>(new QNetworkRequest()), QSharedPointer<QBuffer>(new QBuffer())));
67 response->setReply(reply);
68 return response;
69}
70
71class MockClient : public click::web::Client64class MockClient : public click::web::Client
72{65{
73public:66public:
@@ -76,6 +69,7 @@
76 {69 {
77 }70 }
7871
72 MOCK_METHOD2(signUrl, std::string(const std::string&, const std::string&));
79 // Mocking default arguments: https://groups.google.com/forum/#!topic/googlemock/XrabW20vV7o73 // Mocking default arguments: https://groups.google.com/forum/#!topic/googlemock/XrabW20vV7o
80 MOCK_METHOD6(callImpl, QSharedPointer<click::web::Response>(74 MOCK_METHOD6(callImpl, QSharedPointer<click::web::Response>(
81 const std::string& iri,75 const std::string& iri,
@@ -102,6 +96,16 @@
10296
103 MOCK_METHOD1(has_header, bool(const std::string& header));97 MOCK_METHOD1(has_header, bool(const std::string& header));
104 MOCK_METHOD1(get_header, std::string(const std::string&header));98 MOCK_METHOD1(get_header, std::string(const std::string&header));
99
100 static QSharedPointer<click::web::Response> responseForReply(const QSharedPointer<click::network::Reply>& reply)
101 {
102 auto response = QSharedPointer<click::web::Response>
103 (new click::web::Response(QSharedPointer<QNetworkRequest>(new QNetworkRequest()),
104 QSharedPointer<QBuffer>(new QBuffer())));
105 response->setReply(reply);
106 return response;
107 }
108
105};109};
106110
107}111}
108112
=== modified file 'libclickscope/tests/test_bootstrap.cpp'
--- libclickscope/tests/test_bootstrap.cpp 2016-06-30 20:42:56 +0000
+++ libclickscope/tests/test_bootstrap.cpp 2016-09-21 14:55:05 +0000
@@ -70,7 +70,7 @@
70TEST_F(BootstrapTest, testBootstrapCallsWebservice)70TEST_F(BootstrapTest, testBootstrapCallsWebservice)
71{71{
72 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;72 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
73 auto response = responseForReply(reply.asSharedPtr());73 auto response = MockClient::responseForReply(reply.asSharedPtr());
7474
75 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::BOOTSTRAP_PATH), "GET", _, _, _, _))75 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::BOOTSTRAP_PATH), "GET", _, _, _, _))
76 .Times(1)76 .Times(1)
@@ -81,7 +81,7 @@
81TEST_F(BootstrapTest, testBootstrapJsonIsParsed)81TEST_F(BootstrapTest, testBootstrapJsonIsParsed)
82{82{
83 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;83 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
84 auto response = responseForReply(reply.asSharedPtr());84 auto response = MockClient::responseForReply(reply.asSharedPtr());
8585
86 QByteArray fake_json(FAKE_JSON_BOOTSTRAP.c_str());86 QByteArray fake_json(FAKE_JSON_BOOTSTRAP.c_str());
87 EXPECT_CALL(reply.instance, readAll())87 EXPECT_CALL(reply.instance, readAll())
8888
=== modified file 'libclickscope/tests/test_download_manager.cpp'
--- libclickscope/tests/test_download_manager.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/tests/test_download_manager.cpp 2016-09-21 14:55:05 +0000
@@ -63,6 +63,7 @@
6363
64 virtual void SetUp()64 virtual void SetUp()
65 {65 {
66 sdmPtr.reset(new MockSystemDownloadManager());
66 ssoPtr.reset(new MockCredentialsService());67 ssoPtr.reset(new MockCredentialsService());
67 namPtr.reset(new MockNetworkAccessManager());68 namPtr.reset(new MockNetworkAccessManager());
68 clientPtr.reset(new NiceMock<MockClient>(namPtr));69 clientPtr.reset(new NiceMock<MockClient>(namPtr));
@@ -76,138 +77,165 @@
7677
77}78}
7879
79TEST_F(DownloadManagerTest, testStartCallsWebservice)80TEST_F(DownloadManagerTest, testStartCallsSignUrl)
80{81{
81 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;82 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
82 auto response = responseForReply(reply.asSharedPtr());83 EXPECT_CALL(*sdmPtr, createDownload(_, _, _)).Times(1);
83
84 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
85 .Times(1)
86 .WillOnce(Return(response));
87
88 dmPtr->start("", "", "",84 dmPtr->start("", "", "",
89 [](std::string, click::DownloadManager::Error) {});85 [](std::string, click::DownloadManager::Error) {});
90}86}
9187
92TEST_F(DownloadManagerTest, testStartCallbackCalled)88TEST_F(DownloadManagerTest, testStartDownloadSuccssIsError)
93{89{
94 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;90 auto mockDownload = new MockDownload();
95 auto response = responseForReply(reply.asSharedPtr());91 auto mockError = new MockError();
9692 EXPECT_CALL(*mockDownload, isError())
97 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(0)));93 .Times(1)
98 EXPECT_CALL(reply.instance, readAll())94 .WillOnce(Return(true));
99 .Times(1)95 EXPECT_CALL(*mockDownload, error())
100 .WillOnce(Return(""));96 .Times(1)
101 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))97 .WillOnce(Return(mockError));
102 .Times(1)98 EXPECT_CALL(*mockError, errorString())
103 .WillOnce(Return(response));99 .Times(1)
104 EXPECT_CALL(*this, start_callback(_, _)).Times(1);100 .WillOnce(Return(QStringLiteral("")));
105101
106 dmPtr->start("", "", "",102 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
107 [this](std::string msg, click::DownloadManager::Error err) {103 EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
108 start_callback(msg, err);104 .Times(1)
109 });105 .WillOnce(InvokeArgument<1>(mockDownload));
110 response->replyFinished();106 EXPECT_CALL(*this, start_callback(_, _)).Times(1);
111}107
112108 dmPtr->start("", "", "",
113TEST_F(DownloadManagerTest, testStartHTTPForbidden)109 [this](std::string msg, click::DownloadManager::Error err) {
114{110 start_callback(msg, err);
115 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;111 });
116 auto response = responseForReply(reply.asSharedPtr());112
117113 delete mockError;
118 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(403)));114 delete mockDownload;
119 EXPECT_CALL(reply.instance, readAll())115}
120 .Times(1)116
121 .WillOnce(Return(""));117TEST_F(DownloadManagerTest, testStartDownloadSuccssCallsStart)
122 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))118{
123 .Times(1)119 auto mockDownload = new MockDownload();
124 .WillOnce(Return(response));120 EXPECT_CALL(*mockDownload, isError())
125 EXPECT_CALL(*this, start_callback(StartsWith("Unhandled HTTP response code:"),121 .Times(1)
126 click::DownloadManager::Error::DownloadInstallError)).Times(1);122 .WillOnce(Return(false));
127123 EXPECT_CALL(*mockDownload, start()).Times(1);
128 dmPtr->start("", "", "",124 EXPECT_CALL(*mockDownload, id())
129 [this](std::string msg, click::DownloadManager::Error err) {125 .Times(1)
130 start_callback(msg, err);126 .WillOnce(Return(QStringLiteral("download")));
131 });127
132 response->replyFinished();128 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
133}129 EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
134130 .Times(1)
135TEST_F(DownloadManagerTest, testStartHTTPError)131 .WillOnce(InvokeArgument<1>(mockDownload));
136{132 EXPECT_CALL(*this, start_callback(_, _)).Times(1);
137 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;133
138 auto response = responseForReply(reply.asSharedPtr());134 dmPtr->start("", "", "",
139135 [this](std::string msg, click::DownloadManager::Error err) {
140 EXPECT_CALL(reply.instance, errorString())136 start_callback(msg, err);
141 .WillOnce(Return(QString("ERROR")));137 });
142 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(404)));138
143 EXPECT_CALL(reply.instance, readAll())139 delete mockDownload;
144 .Times(1)140}
145 .WillOnce(Return(""));141
146 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))142TEST_F(DownloadManagerTest, testStartErrorCallback)
147 .Times(1)143{
148 .WillOnce(Return(response));144 auto mockDownload = new MockDownload();
149 EXPECT_CALL(*this, start_callback("ERROR (203)",145 auto mockError = new MockError();
150 click::DownloadManager::Error::DownloadInstallError)).Times(1);146 EXPECT_CALL(*mockDownload, error())
151147 .Times(1)
152 dmPtr->start("", "", "",148 .WillOnce(Return(mockError));
153 [this](std::string msg, click::DownloadManager::Error err) {149 EXPECT_CALL(*mockError, errorString())
154 start_callback(msg, err);150 .Times(1)
155 });151 .WillOnce(Return(QStringLiteral("")));
156 response->errorHandler(QNetworkReply::ContentNotFoundError);152
157}153 EXPECT_CALL(*clientPtr, signUrl(_, "GET")).Times(1);
158154 EXPECT_CALL(*sdmPtr, createDownload(_, _, _))
159TEST_F(DownloadManagerTest, testStartCredentialsError)155 .Times(1)
160{156 .WillOnce(InvokeArgument<2>(mockDownload));
161 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;157 EXPECT_CALL(*this, start_callback(_, _)).Times(1);
162 auto response = responseForReply(reply.asSharedPtr());158
163159 dmPtr->start("", "", "",
164 EXPECT_CALL(reply.instance, errorString())160 [this](std::string msg, click::DownloadManager::Error err) {
165 .WillOnce(Return(QString("ERROR")));161 start_callback(msg, err);
166 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(401)));162 });
167 EXPECT_CALL(reply.instance, readAll())163
168 .Times(1)164 delete mockError;
169 .WillOnce(Return(""));165 delete mockDownload;
170 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))166}
171 .Times(1)167
172 .WillOnce(Return(response));168TEST_F(DownloadManagerTest, testGetProgressDownloadFound)
173 EXPECT_CALL(*ssoPtr, invalidateCredentials());169{
174 EXPECT_CALL(*this, start_callback("ERROR (201)",170 auto mockDownloadsList = new MockDownloadsList();
175 click::DownloadManager::Error::CredentialsError)).Times(1);171 auto mockDownload = QSharedPointer<MockDownload>(new MockDownload());
176172
177 dmPtr->start("", "", "test.package",173 QList<QSharedPointer<Ubuntu::DownloadManager::Download>> downloads{mockDownload};
178 [this](std::string msg, click::DownloadManager::Error err) {174
179 start_callback(msg, err);175 EXPECT_CALL(*mockDownload, id())
180 });176 .Times(1)
181 response->errorHandler(QNetworkReply::ContentAccessDenied);177 .WillOnce(Return("download"));
182}178 EXPECT_CALL(*mockDownloadsList, downloads())
183179 .Times(1)
184// FIXME: createDownload() SEGV under tests180 .WillOnce(Return(downloads));
185TEST_F(DownloadManagerTest, DISABLED_testStartDownloadCreated)181 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
186{182 .Times(1)
187 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;183 .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
188 auto response = responseForReply(reply.asSharedPtr());184 mockDownloadsList));
189185 dmPtr->get_progress("com.example.test",
190 EXPECT_CALL(reply.instance, rawHeader(QByteArray("X-Click-Token")))186 [this](std::string object_path) {
191 .Times(1)187 progress_callback(object_path);
192 .WillOnce(Return(QString("clicktoken")));188 });
193 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));189
194 EXPECT_CALL(reply.instance, readAll())190 delete mockDownloadsList;
195 .Times(1)191}
196 .WillOnce(Return(""));192
197 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))193TEST_F(DownloadManagerTest, testGetProgressMultipleDownloadsFound)
198 .Times(1)194{
199 .WillOnce(Return(response));195 auto mockDownloadsList = new MockDownloadsList();
200196 auto mockDownload = QSharedPointer<MockDownload>(new MockDownload());
201 EXPECT_CALL(*sdmPtr, createDownload(_, _, _));197 auto mockDownload2 = QSharedPointer<MockDownload>(new MockDownload());
202 dmPtr->start("", "", "test.package",198
203 [this](std::string msg, click::DownloadManager::Error err) {199 QList<QSharedPointer<Ubuntu::DownloadManager::Download>> downloads{mockDownload, mockDownload2};
204 start_callback(msg, err);200
205 });201 EXPECT_CALL(*mockDownload, id())
206 response->replyFinished();202 .Times(1)
207}203 .WillOnce(Return("download"));
208204 EXPECT_CALL(*mockDownloadsList, downloads())
209// FIXME: getAllDownloadsWithMetadata() SEGV under tests205 .Times(1)
210TEST_F(DownloadManagerTest, DISABLED_testGetProgressNoDownloads)206 .WillOnce(Return(downloads));
207 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
208 .Times(1)
209 .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
210 mockDownloadsList));
211 dmPtr->get_progress("com.example.test",
212 [this](std::string object_path) {
213 progress_callback(object_path);
214 });
215
216 delete mockDownloadsList;
217}
218
219TEST_F(DownloadManagerTest, testGetProgressNoDownloadsFound)
220{
221 auto mockDownloadsList = new MockDownloadsList();
222 QList<QSharedPointer<Ubuntu::DownloadManager::Download>> emptyDownloads{};
223 EXPECT_CALL(*mockDownloadsList, downloads())
224 .Times(1)
225 .WillOnce(Return(emptyDownloads));
226 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
227 .Times(1)
228 .WillOnce(InvokeArgument<2>(QStringLiteral(""), QStringLiteral(""),
229 mockDownloadsList));
230 dmPtr->get_progress("com.example.test",
231 [this](std::string object_path) {
232 progress_callback(object_path);
233 });
234
235 delete mockDownloadsList;
236}
237
238TEST_F(DownloadManagerTest, testGetProgressErrorCallback)
211{239{
212 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))240 EXPECT_CALL(*sdmPtr, getAllDownloadsWithMetadata(_, _, _, _))
213 .Times(1)241 .Times(1)
214242
=== modified file 'libclickscope/tests/test_index.cpp'
--- libclickscope/tests/test_index.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/tests/test_index.cpp 2016-09-21 14:55:05 +0000
@@ -66,7 +66,7 @@
66};66};
6767
6868
69class IndexTest : public ::testing::Test {69class SimpleIndexTest : public ::testing::Test {
70protected:70protected:
71 QSharedPointer<MockClient> clientPtr;71 QSharedPointer<MockClient> clientPtr;
72 QSharedPointer<MockNetworkAccessManager> namPtr;72 QSharedPointer<MockNetworkAccessManager> namPtr;
@@ -86,6 +86,18 @@
86 MOCK_METHOD2(details_callback, void(click::PackageDetails, click::Index::Error));86 MOCK_METHOD2(details_callback, void(click::PackageDetails, click::Index::Error));
87};87};
8888
89class IndexTest : public SimpleIndexTest {
90 virtual void SetUp() {
91 SimpleIndexTest::SetUp();
92 EXPECT_CALL(*configPtr, get_architecture())
93 .Times(1)
94 .WillOnce(Return(fake_arch));
95 EXPECT_CALL(*configPtr, get_available_frameworks())
96 .Times(1)
97 .WillOnce(Return(fake_frameworks));
98 }
99};
100
89class MockPackageManager : public click::PackageManager, public ::testing::Test101class MockPackageManager : public click::PackageManager, public ::testing::Test
90{102{
91public:103public:
@@ -97,14 +109,8 @@
97TEST_F(IndexTest, testSearchCallsWebservice)109TEST_F(IndexTest, testSearchCallsWebservice)
98{110{
99 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;111 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
100 auto response = responseForReply(reply.asSharedPtr());112 auto response = MockClient::responseForReply(reply.asSharedPtr());
101113
102 EXPECT_CALL(*configPtr, get_architecture())
103 .Times(1)
104 .WillOnce(Return(fake_arch));
105 EXPECT_CALL(*configPtr, get_available_frameworks())
106 .Times(1)
107 .WillOnce(Return(fake_frameworks));
108 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))114 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
109 .Times(1)115 .Times(1)
110 .WillOnce(Return(response));116 .WillOnce(Return(response));
@@ -120,14 +126,8 @@
120TEST_F(IndexTest, testSearchQueryIsLowercase)126TEST_F(IndexTest, testSearchQueryIsLowercase)
121{127{
122 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;128 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
123 auto response = responseForReply(reply.asSharedPtr());129 auto response = MockClient::responseForReply(reply.asSharedPtr());
124130
125 EXPECT_CALL(*configPtr, get_architecture())
126 .Times(1)
127 .WillOnce(Return(fake_arch));
128 EXPECT_CALL(*configPtr, get_available_frameworks())
129 .Times(1)
130 .WillOnce(Return(fake_frameworks));
131 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, QueryContains("foobar")))131 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, QueryContains("foobar")))
132 .Times(1)132 .Times(1)
133 .WillOnce(Return(response));133 .WillOnce(Return(response));
@@ -139,14 +139,8 @@
139TEST_F(IndexTest, testSearchSignsCall)139TEST_F(IndexTest, testSearchSignsCall)
140{140{
141 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;141 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
142 auto response = responseForReply(reply.asSharedPtr());142 auto response = MockClient::responseForReply(reply.asSharedPtr());
143143
144 EXPECT_CALL(*configPtr, get_architecture())
145 .Times(1)
146 .WillOnce(Return(fake_arch));
147 EXPECT_CALL(*configPtr, get_available_frameworks())
148 .Times(1)
149 .WillOnce(Return(fake_frameworks));
150 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))144 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
151 .Times(1)145 .Times(1)
152 .WillOnce(Return(response));146 .WillOnce(Return(response));
@@ -154,17 +148,119 @@
154 indexPtr->search("", "", [](click::Packages, click::Packages) {});148 indexPtr->search("", "", [](click::Packages, click::Packages) {});
155}149}
156150
151TEST_F(IndexTest, testSearchSnapsCallsWebservice)
152{
153 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
154 auto response = MockClient::responseForReply(reply.asSharedPtr());
155
156 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
157 .Times(1)
158 .WillOnce(Return(response));
159
160 indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
161}
162
163TEST_F(IndexTest, testSearchSnapsSendsRightPath)
164{
165 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
166 auto response = MockClient::responseForReply(reply.asSharedPtr());
167
168 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::SNAP_SEARCH_PATH),
169 _, _, _, _, _))
170 .Times(1)
171 .WillOnce(Return(response));
172
173 indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
174}
175
176TEST_F(IndexTest, testSearchSnapsQueryIsLowercase)
177{
178 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
179 auto response = MockClient::responseForReply(reply.asSharedPtr());
180
181 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, QueryContains("foobar")))
182 .Times(1)
183 .WillOnce(Return(response));
184
185 indexPtr->search_snaps("FooBar", [](click::Packages, click::Packages) {});
186}
187
188
189TEST_F(IndexTest, testSearchSnapsSignsCall)
190{
191 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
192 auto response = MockClient::responseForReply(reply.asSharedPtr());
193
194 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
195 .Times(1)
196 .WillOnce(Return(response));
197
198 indexPtr->search_snaps("", [](click::Packages, click::Packages) {});
199}
200
201TEST_F(IndexTest, testSearchSnapsIsCancellable)
202{
203 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
204 auto response = MockClient::responseForReply(reply.asSharedPtr());
205
206 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
207 .Times(1)
208 .WillOnce(Return(response));
209
210 auto search_operation = indexPtr->search_snaps("", [](click::Packages,
211 click::Packages) {});
212 EXPECT_CALL(reply.instance, abort()).Times(1);
213 search_operation.cancel();
214}
215
216TEST_F(IndexTest, testSearchSnapsEmptyJsonIsParsed)
217{
218 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
219 auto response = MockClient::responseForReply(reply.asSharedPtr());
220
221 QByteArray fake_json("[]");
222 EXPECT_CALL(reply.instance, readAll())
223 .Times(1)
224 .WillOnce(Return(fake_json));
225 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
226 .Times(1)
227 .WillOnce(Return(response));
228 click::Packages empty_package_list;
229 EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1);
230
231 indexPtr->search_snaps("", [this](click::Packages packages,
232 click::Packages recommends){
233 search_callback(packages, recommends);
234 });
235 response->replyFinished();
236}
237
238TEST_F(IndexTest, testSearchSnapsNetworkErrorIgnored)
239{
240 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
241 auto response = MockClient::responseForReply(reply.asSharedPtr());
242
243 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
244 .Times(1)
245 .WillOnce(Return(response));
246 EXPECT_CALL(reply.instance, errorString()).Times(1)
247 .WillOnce(Return("fake error"));
248 indexPtr->search_snaps("", [this](click::Packages packages,
249 click::Packages recommends){
250 search_callback(packages, recommends);
251 });
252
253 click::Packages empty_package_list;
254 EXPECT_CALL(*this, search_callback(empty_package_list, _)).Times(1);
255
256 emit reply.instance.error(QNetworkReply::UnknownNetworkError);
257}
258
157TEST_F(IndexTest, testBootstrapSignsCall)259TEST_F(IndexTest, testBootstrapSignsCall)
158{260{
159 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;261 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
160 auto response = responseForReply(reply.asSharedPtr());262 auto response = MockClient::responseForReply(reply.asSharedPtr());
161263
162 EXPECT_CALL(*configPtr, get_architecture())
163 .Times(1)
164 .WillOnce(Return(fake_arch));
165 EXPECT_CALL(*configPtr, get_available_frameworks())
166 .Times(1)
167 .WillOnce(Return(fake_frameworks));
168 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))264 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
169 .Times(1)265 .Times(1)
170 .WillOnce(Return(response));266 .WillOnce(Return(response));
@@ -175,14 +271,8 @@
175TEST_F(IndexTest, testDepartmentsSignsCall)271TEST_F(IndexTest, testDepartmentsSignsCall)
176{272{
177 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;273 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
178 auto response = responseForReply(reply.asSharedPtr());274 auto response = MockClient::responseForReply(reply.asSharedPtr());
179275
180 EXPECT_CALL(*configPtr, get_architecture())
181 .Times(1)
182 .WillOnce(Return(fake_arch));
183 EXPECT_CALL(*configPtr, get_available_frameworks())
184 .Times(1)
185 .WillOnce(Return(fake_frameworks));
186 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))276 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
187 .Times(1)277 .Times(1)
188 .WillOnce(Return(response));278 .WillOnce(Return(response));
@@ -193,7 +283,7 @@
193TEST_F(IndexTest, testDetailsSignsCall)283TEST_F(IndexTest, testDetailsSignsCall)
194{284{
195 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;285 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
196 auto response = responseForReply(reply.asSharedPtr());286 auto response = MockClient::responseForReply(reply.asSharedPtr());
197287
198 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))288 EXPECT_CALL(*clientPtr, callImpl(_, _, true, _, _, _))
199 .Times(1)289 .Times(1)
@@ -205,14 +295,8 @@
205TEST_F(IndexTest, testSearchSendsRightPath)295TEST_F(IndexTest, testSearchSendsRightPath)
206{296{
207 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;297 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
208 auto response = responseForReply(reply.asSharedPtr());298 auto response = MockClient::responseForReply(reply.asSharedPtr());
209299
210 EXPECT_CALL(*configPtr, get_architecture())
211 .Times(1)
212 .WillOnce(Return(fake_arch));
213 EXPECT_CALL(*configPtr, get_available_frameworks())
214 .Times(1)
215 .WillOnce(Return(fake_frameworks));
216 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::SEARCH_PATH),300 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::SEARCH_PATH),
217 _, _, _, _, _))301 _, _, _, _, _))
218 .Times(1)302 .Times(1)
@@ -224,18 +308,12 @@
224TEST_F(IndexTest, testSearchCallbackIsCalled)308TEST_F(IndexTest, testSearchCallbackIsCalled)
225{309{
226 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;310 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
227 auto response = responseForReply(reply.asSharedPtr());311 auto response = MockClient::responseForReply(reply.asSharedPtr());
228312
229 QByteArray fake_json("[]");313 QByteArray fake_json("[]");
230 EXPECT_CALL(reply.instance, readAll())314 EXPECT_CALL(reply.instance, readAll())
231 .Times(1)315 .Times(1)
232 .WillOnce(Return(fake_json));316 .WillOnce(Return(fake_json));
233 EXPECT_CALL(*configPtr, get_architecture())
234 .Times(1)
235 .WillOnce(Return(fake_arch));
236 EXPECT_CALL(*configPtr, get_available_frameworks())
237 .Times(1)
238 .WillOnce(Return(fake_frameworks));
239 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))317 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
240 .Times(1)318 .Times(1)
241 .WillOnce(Return(response));319 .WillOnce(Return(response));
@@ -251,18 +329,12 @@
251TEST_F(IndexTest, testSearchEmptyJsonIsParsed)329TEST_F(IndexTest, testSearchEmptyJsonIsParsed)
252{330{
253 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;331 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
254 auto response = responseForReply(reply.asSharedPtr());332 auto response = MockClient::responseForReply(reply.asSharedPtr());
255333
256 QByteArray fake_json("[]");334 QByteArray fake_json("[]");
257 EXPECT_CALL(reply.instance, readAll())335 EXPECT_CALL(reply.instance, readAll())
258 .Times(1)336 .Times(1)
259 .WillOnce(Return(fake_json));337 .WillOnce(Return(fake_json));
260 EXPECT_CALL(*configPtr, get_architecture())
261 .Times(1)
262 .WillOnce(Return(fake_arch));
263 EXPECT_CALL(*configPtr, get_available_frameworks())
264 .Times(1)
265 .WillOnce(Return(fake_frameworks));
266 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))338 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
267 .Times(1)339 .Times(1)
268 .WillOnce(Return(response));340 .WillOnce(Return(response));
@@ -279,18 +351,12 @@
279TEST_F(IndexTest, testSearchSingleJsonIsParsed)351TEST_F(IndexTest, testSearchSingleJsonIsParsed)
280{352{
281 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;353 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
282 auto response = responseForReply(reply.asSharedPtr());354 auto response = MockClient::responseForReply(reply.asSharedPtr());
283355
284 QByteArray fake_json(FAKE_JSON_SEARCH_RESULT_ONE.c_str());356 QByteArray fake_json(FAKE_JSON_SEARCH_RESULT_ONE.c_str());
285 EXPECT_CALL(reply.instance, readAll())357 EXPECT_CALL(reply.instance, readAll())
286 .Times(1)358 .Times(1)
287 .WillOnce(Return(fake_json));359 .WillOnce(Return(fake_json));
288 EXPECT_CALL(*configPtr, get_architecture())
289 .Times(1)
290 .WillOnce(Return(fake_arch));
291 EXPECT_CALL(*configPtr, get_available_frameworks())
292 .Times(1)
293 .WillOnce(Return(fake_frameworks));
294 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))360 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
295 .Times(1)361 .Times(1)
296 .WillOnce(Return(response));362 .WillOnce(Return(response));
@@ -315,14 +381,8 @@
315TEST_F(IndexTest, testSearchIsCancellable)381TEST_F(IndexTest, testSearchIsCancellable)
316{382{
317 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;383 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
318 auto response = responseForReply(reply.asSharedPtr());384 auto response = MockClient::responseForReply(reply.asSharedPtr());
319385
320 EXPECT_CALL(*configPtr, get_architecture())
321 .Times(1)
322 .WillOnce(Return(fake_arch));
323 EXPECT_CALL(*configPtr, get_available_frameworks())
324 .Times(1)
325 .WillOnce(Return(fake_frameworks));
326 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))386 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
327 .Times(1)387 .Times(1)
328 .WillOnce(Return(response));388 .WillOnce(Return(response));
@@ -341,14 +401,8 @@
341TEST_F(IndexTest, testSearchNetworkErrorIgnored)401TEST_F(IndexTest, testSearchNetworkErrorIgnored)
342{402{
343 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;403 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
344 auto response = responseForReply(reply.asSharedPtr());404 auto response = MockClient::responseForReply(reply.asSharedPtr());
345405
346 EXPECT_CALL(*configPtr, get_architecture())
347 .Times(1)
348 .WillOnce(Return(fake_arch));
349 EXPECT_CALL(*configPtr, get_available_frameworks())
350 .Times(1)
351 .WillOnce(Return(fake_frameworks));
352 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))406 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
353 .Times(1)407 .Times(1)
354 .WillOnce(Return(response));408 .WillOnce(Return(response));
@@ -367,7 +421,7 @@
367TEST_F(IndexTest, testGetDetailsCallsWebservice)421TEST_F(IndexTest, testGetDetailsCallsWebservice)
368{422{
369 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;423 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
370 auto response = responseForReply(reply.asSharedPtr());424 auto response = MockClient::responseForReply(reply.asSharedPtr());
371425
372 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))426 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
373 .Times(1)427 .Times(1)
@@ -379,7 +433,7 @@
379TEST_F(IndexTest, testGetDetailsSendsPackagename)433TEST_F(IndexTest, testGetDetailsSendsPackagename)
380{434{
381 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;435 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
382 auto response = responseForReply(reply.asSharedPtr());436 auto response = MockClient::responseForReply(reply.asSharedPtr());
383437
384 EXPECT_CALL(*clientPtr, callImpl(EndsWith(FAKE_PACKAGENAME),438 EXPECT_CALL(*clientPtr, callImpl(EndsWith(FAKE_PACKAGENAME),
385 _, _, _, _, _))439 _, _, _, _, _))
@@ -392,7 +446,7 @@
392TEST_F(IndexTest, testGetDetailsSendsRightPath)446TEST_F(IndexTest, testGetDetailsSendsRightPath)
393{447{
394 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;448 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
395 auto response = responseForReply(reply.asSharedPtr());449 auto response = MockClient::responseForReply(reply.asSharedPtr());
396450
397 EXPECT_CALL(*clientPtr, callImpl(StartsWith(click::SEARCH_BASE_URL +451 EXPECT_CALL(*clientPtr, callImpl(StartsWith(click::SEARCH_BASE_URL +
398 click::DETAILS_PATH),452 click::DETAILS_PATH),
@@ -406,7 +460,7 @@
406TEST_F(IndexTest, testGetDetailsCallbackIsCalled)460TEST_F(IndexTest, testGetDetailsCallbackIsCalled)
407{461{
408 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;462 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
409 auto response = responseForReply(reply.asSharedPtr());463 auto response = MockClient::responseForReply(reply.asSharedPtr());
410464
411 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());465 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());
412 EXPECT_CALL(reply.instance, readAll())466 EXPECT_CALL(reply.instance, readAll())
@@ -425,7 +479,7 @@
425TEST_F(IndexTest, testGetDetailsJsonIsParsed)479TEST_F(IndexTest, testGetDetailsJsonIsParsed)
426{480{
427 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;481 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
428 auto response = responseForReply(reply.asSharedPtr());482 auto response = MockClient::responseForReply(reply.asSharedPtr());
429483
430 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());484 QByteArray fake_json(FAKE_JSON_PACKAGE_DETAILS.c_str());
431 EXPECT_CALL(reply.instance, readAll())485 EXPECT_CALL(reply.instance, readAll())
@@ -486,7 +540,7 @@
486TEST_F(IndexTest, testGetDetailsJsonUtf8)540TEST_F(IndexTest, testGetDetailsJsonUtf8)
487{541{
488 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;542 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
489 auto response = responseForReply(reply.asSharedPtr());543 auto response = MockClient::responseForReply(reply.asSharedPtr());
490544
491 QByteArray appname_utf8("\xe5\xb0\x8f\xe6\xb5\xb7");545 QByteArray appname_utf8("\xe5\xb0\x8f\xe6\xb5\xb7");
492 QByteArray appname_json("\\u5c0f\\u6d77");546 QByteArray appname_json("\\u5c0f\\u6d77");
@@ -554,7 +608,7 @@
554TEST_F(IndexTest, testGetDetailsNetworkErrorReported)608TEST_F(IndexTest, testGetDetailsNetworkErrorReported)
555{609{
556 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;610 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
557 auto response = responseForReply(reply.asSharedPtr());611 auto response = MockClient::responseForReply(reply.asSharedPtr());
558612
559 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))613 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
560 .Times(1)614 .Times(1)
@@ -571,7 +625,7 @@
571TEST_F(IndexTest, testGetDetailsIsCancellable)625TEST_F(IndexTest, testGetDetailsIsCancellable)
572{626{
573 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;627 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
574 auto response = responseForReply(reply.asSharedPtr());628 auto response = MockClient::responseForReply(reply.asSharedPtr());
575629
576 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))630 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
577 .Times(1)631 .Times(1)
@@ -582,7 +636,7 @@
582 get_details_operation.cancel();636 get_details_operation.cancel();
583}637}
584638
585TEST_F(IndexTest, testGetBaseUrl)639TEST_F(SimpleIndexTest, testGetBaseUrl)
586{640{
587 const char *value = getenv(click::SEARCH_BASE_URL_ENVVAR.c_str());641 const char *value = getenv(click::SEARCH_BASE_URL_ENVVAR.c_str());
588 if (value != NULL) {642 if (value != NULL) {
@@ -592,7 +646,7 @@
592 646
593}647}
594648
595TEST_F(IndexTest, testGetBaseUrlFromEnv)649TEST_F(SimpleIndexTest, testGetBaseUrlFromEnv)
596{650{
597 ASSERT_TRUE(setenv(click::SEARCH_BASE_URL_ENVVAR.c_str(),651 ASSERT_TRUE(setenv(click::SEARCH_BASE_URL_ENVVAR.c_str(),
598 FAKE_SERVER.c_str(), 1) == 0);652 FAKE_SERVER.c_str(), 1) == 0);
@@ -600,14 +654,14 @@
600 ASSERT_TRUE(unsetenv(click::SEARCH_BASE_URL_ENVVAR.c_str()) == 0);654 ASSERT_TRUE(unsetenv(click::SEARCH_BASE_URL_ENVVAR.c_str()) == 0);
601}655}
602656
603TEST_F(IndexTest, testPackageListsFromJsonNodeNoRecommends)657TEST_F(SimpleIndexTest, testPackageListsFromJsonNodeNoRecommends)
604{658{
605 auto lists = indexPtr->package_lists_from_json(FAKE_JSON_SEARCH_RESULT_ONE);659 auto lists = indexPtr->package_lists_from_json(FAKE_JSON_SEARCH_RESULT_ONE);
606 EXPECT_EQ(1, lists.first.size());660 EXPECT_EQ(1, lists.first.size());
607 EXPECT_EQ(0, lists.second.size());661 EXPECT_EQ(0, lists.second.size());
608}662}
609663
610TEST_F(IndexTest, testPackageListsFromJsonNodeHasRecommends)664TEST_F(SimpleIndexTest, testPackageListsFromJsonNodeHasRecommends)
611{665{
612 auto lists = indexPtr->package_lists_from_json(FAKE_JSON_SEARCH_RESULT_RECOMMENDS);666 auto lists = indexPtr->package_lists_from_json(FAKE_JSON_SEARCH_RESULT_RECOMMENDS);
613 EXPECT_EQ(1, lists.second.size());667 EXPECT_EQ(1, lists.second.size());
@@ -668,3 +722,15 @@
668 EXPECT_NE(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find(fake_fwk_1));722 EXPECT_NE(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find(fake_fwk_1));
669 EXPECT_NE(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find(fake_fwk_2));723 EXPECT_NE(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find(fake_fwk_2));
670}724}
725
726TEST_F(QueryStringTest, testBuildHeadersFrameworksEmpty)
727{
728 EXPECT_CALL(*configPtr, get_architecture()).Times(1).WillOnce(Return(fake_arch));
729 EXPECT_CALL(*configPtr, get_available_frameworks())
730 .Times(1)
731 .WillOnce(Return(std::vector<std::string>{}));
732 auto hdrs = indexPtr->build_headers();
733 EXPECT_EQ(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find(fake_fwk_1));
734 EXPECT_EQ(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find(fake_fwk_2));
735 ASSERT_NE(std::string::npos, hdrs["X-Ubuntu-Frameworks"].find("none"));
736}
671737
=== modified file 'libclickscope/tests/test_pay.cpp'
--- libclickscope/tests/test_pay.cpp 2016-06-30 20:42:56 +0000
+++ libclickscope/tests/test_pay.cpp 2016-09-21 14:55:05 +0000
@@ -68,7 +68,7 @@
68TEST_F(PayTest, testPayPackageRefundCalled)68TEST_F(PayTest, testPayPackageRefundCalled)
69{69{
70 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;70 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
71 auto response = responseForReply(reply.asSharedPtr());71 auto response = MockClient::responseForReply(reply.asSharedPtr());
7272
73 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);73 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);
74 EXPECT_FALSE(package->refund("foo"));74 EXPECT_FALSE(package->refund("foo"));
@@ -77,7 +77,7 @@
77TEST_F(PayTest, testPayPackageRefundNotCalledIfCallbackExists)77TEST_F(PayTest, testPayPackageRefundNotCalledIfCallbackExists)
78{78{
79 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;79 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
80 auto response = responseForReply(reply.asSharedPtr());80 auto response = MockClient::responseForReply(reply.asSharedPtr());
8181
82 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_REFUND;82 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_REFUND;
83 package->callbacks[callback_id] = [](const std::string&, bool) {};83 package->callbacks[callback_id] = [](const std::string&, bool) {};
@@ -88,7 +88,7 @@
88TEST_F(PayTest, testRefundReturnsTrueForPurchasedItem)88TEST_F(PayTest, testRefundReturnsTrueForPurchasedItem)
89{89{
90 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;90 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
91 auto response = responseForReply(reply.asSharedPtr());91 auto response = MockClient::responseForReply(reply.asSharedPtr());
9292
93 package->success = true;93 package->success = true;
94 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);94 EXPECT_CALL(*package, do_pay_package_refund("foo")).Times(1);
@@ -98,7 +98,7 @@
98TEST_F(PayTest, testPayPackageVerifyCalled)98TEST_F(PayTest, testPayPackageVerifyCalled)
99{99{
100 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;100 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
101 auto response = responseForReply(reply.asSharedPtr());101 auto response = MockClient::responseForReply(reply.asSharedPtr());
102102
103 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);103 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);
104 EXPECT_FALSE(package->verify("foo"));104 EXPECT_FALSE(package->verify("foo"));
@@ -107,7 +107,7 @@
107TEST_F(PayTest, testPayPackageVerifyNotCalledIfCallbackExists)107TEST_F(PayTest, testPayPackageVerifyNotCalledIfCallbackExists)
108{108{
109 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;109 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
110 auto response = responseForReply(reply.asSharedPtr());110 auto response = MockClient::responseForReply(reply.asSharedPtr());
111111
112 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_VERIFY;112 std::string callback_id = std::string{"foo"} + pay::APPENDAGE_VERIFY;
113 package->callbacks[callback_id] = [](const std::string&, bool) {};113 package->callbacks[callback_id] = [](const std::string&, bool) {};
@@ -118,7 +118,7 @@
118TEST_F(PayTest, testVerifyReturnsTrueForPurchasedItem)118TEST_F(PayTest, testVerifyReturnsTrueForPurchasedItem)
119{119{
120 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;120 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
121 auto response = responseForReply(reply.asSharedPtr());121 auto response = MockClient::responseForReply(reply.asSharedPtr());
122122
123 package->success = true;123 package->success = true;
124 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);124 EXPECT_CALL(*package, do_pay_package_verify("foo")).Times(1);
@@ -128,7 +128,7 @@
128TEST_F(PayTest, testGetPurchasesCallsWebservice)128TEST_F(PayTest, testGetPurchasesCallsWebservice)
129{129{
130 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;130 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
131 auto response = responseForReply(reply.asSharedPtr());131 auto response = MockClient::responseForReply(reply.asSharedPtr());
132132
133 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))133 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
134 .Times(1)134 .Times(1)
@@ -140,7 +140,7 @@
140TEST_F(PayTest, testGetPurchasesSendsCorrectPath)140TEST_F(PayTest, testGetPurchasesSendsCorrectPath)
141{141{
142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
143 auto response = responseForReply(reply.asSharedPtr());143 auto response = MockClient::responseForReply(reply.asSharedPtr());
144144
145 EXPECT_CALL(*clientPtr, callImpl(EndsWith(pay::PURCHASES_API_PATH),145 EXPECT_CALL(*clientPtr, callImpl(EndsWith(pay::PURCHASES_API_PATH),
146 _, _, _, _, _))146 _, _, _, _, _))
@@ -153,7 +153,7 @@
153TEST_F(PayTest, testGetPurchasesCallbackCalled)153TEST_F(PayTest, testGetPurchasesCallbackCalled)
154{154{
155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
156 auto response = responseForReply(reply.asSharedPtr());156 auto response = MockClient::responseForReply(reply.asSharedPtr());
157157
158 QByteArray fake_json("[]");158 QByteArray fake_json("[]");
159 EXPECT_CALL(reply.instance, readAll())159 EXPECT_CALL(reply.instance, readAll())
@@ -173,7 +173,7 @@
173TEST_F(PayTest, testGetPurchasesEmptyJsonIsParsed)173TEST_F(PayTest, testGetPurchasesEmptyJsonIsParsed)
174{174{
175 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;175 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
176 auto response = responseForReply(reply.asSharedPtr());176 auto response = MockClient::responseForReply(reply.asSharedPtr());
177177
178 QByteArray fake_json("[]");178 QByteArray fake_json("[]");
179 EXPECT_CALL(reply.instance, readAll())179 EXPECT_CALL(reply.instance, readAll())
@@ -194,7 +194,7 @@
194TEST_F(PayTest, testGetPurchasesSingleJsonIsParsedNullTimestamp)194TEST_F(PayTest, testGetPurchasesSingleJsonIsParsedNullTimestamp)
195{195{
196 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;196 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
197 auto response = responseForReply(reply.asSharedPtr());197 auto response = MockClient::responseForReply(reply.asSharedPtr());
198198
199 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON_NULL_TIMESTAMP);199 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON_NULL_TIMESTAMP);
200 EXPECT_CALL(reply.instance, readAll())200 EXPECT_CALL(reply.instance, readAll())
@@ -215,7 +215,7 @@
215TEST_F(PayTest, testGetPurchasesTimestampIsParsed)215TEST_F(PayTest, testGetPurchasesTimestampIsParsed)
216{216{
217 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;217 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
218 auto response = responseForReply(reply.asSharedPtr());218 auto response = MockClient::responseForReply(reply.asSharedPtr());
219219
220 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON);220 QByteArray fake_json(FAKE_PURCHASES_LIST_JSON);
221 EXPECT_CALL(reply.instance, readAll())221 EXPECT_CALL(reply.instance, readAll())
@@ -237,7 +237,7 @@
237TEST_F(PayTest, testGetPurchasesIsCancellable)237TEST_F(PayTest, testGetPurchasesIsCancellable)
238{238{
239 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;239 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
240 auto response = responseForReply(reply.asSharedPtr());240 auto response = MockClient::responseForReply(reply.asSharedPtr());
241241
242 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))242 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
243 .Times(1)243 .Times(1)
244244
=== modified file 'libclickscope/tests/test_preview.cpp'
--- libclickscope/tests/test_preview.cpp 2016-07-13 20:30:09 +0000
+++ libclickscope/tests/test_preview.cpp 2016-09-21 14:55:05 +0000
@@ -1,5 +1,5 @@
1/*1/*
2 * Copyright (C) 2014 Canonical Ltd.2 * Copyright (C) 2014-2016 Canonical Ltd.
3 *3 *
4 * This program is free software: you can redistribute it and/or modify it4 * This program is free software: you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 3, as published5 * under the terms of the GNU General Public License version 3, as published
@@ -64,7 +64,7 @@
64 FakeIndex() {64 FakeIndex() {
6565
66 }66 }
67 click::web::Cancellable get_details(const std::string& /*package_name*/, std::function<void(click::PackageDetails, Error)> callback, bool) override {67 click::web::Cancellable get_details(const std::string& /*package_name*/, std::function<void(click::PackageDetails, Error)> callback, bool, bool) override {
68 callback(click::PackageDetails(), Error::NetworkError);68 callback(click::PackageDetails(), Error::NetworkError);
69 return click::web::Cancellable();69 return click::web::Cancellable();
70 }70 }
7171
=== modified file 'libclickscope/tests/test_reviews.cpp'
--- libclickscope/tests/test_reviews.cpp 2016-05-10 13:42:12 +0000
+++ libclickscope/tests/test_reviews.cpp 2016-09-21 14:55:05 +0000
@@ -140,7 +140,7 @@
140TEST_F(ReviewsTest, testFetchReviewsCallsWebservice)140TEST_F(ReviewsTest, testFetchReviewsCallsWebservice)
141{141{
142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;142 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
143 auto response = responseForReply(reply.asSharedPtr());143 auto response = MockClient::responseForReply(reply.asSharedPtr());
144144
145 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))145 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
146 .Times(1)146 .Times(1)
@@ -153,7 +153,7 @@
153TEST_F(ReviewsTest, testFetchReviewsDoesNotSignCall)153TEST_F(ReviewsTest, testFetchReviewsDoesNotSignCall)
154{154{
155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;155 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
156 auto response = responseForReply(reply.asSharedPtr());156 auto response = MockClient::responseForReply(reply.asSharedPtr());
157157
158 EXPECT_CALL(*clientPtr, callImpl(_, _, false, _, _, _))158 EXPECT_CALL(*clientPtr, callImpl(_, _, false, _, _, _))
159 .Times(1)159 .Times(1)
@@ -166,7 +166,7 @@
166TEST_F(ReviewsTest, testFetchReviewsSendsQueryAsParam)166TEST_F(ReviewsTest, testFetchReviewsSendsQueryAsParam)
167{167{
168 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;168 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
169 auto response = responseForReply(reply.asSharedPtr());169 auto response = MockClient::responseForReply(reply.asSharedPtr());
170170
171 click::web::CallParams params;171 click::web::CallParams params;
172 params.add(click::REVIEWS_QUERY_ARGNAME, FAKE_PACKAGENAME);172 params.add(click::REVIEWS_QUERY_ARGNAME, FAKE_PACKAGENAME);
@@ -181,7 +181,7 @@
181TEST_F(ReviewsTest, testFetchReviewsSendsCorrectPath)181TEST_F(ReviewsTest, testFetchReviewsSendsCorrectPath)
182{182{
183 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;183 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
184 auto response = responseForReply(reply.asSharedPtr());184 auto response = MockClient::responseForReply(reply.asSharedPtr());
185185
186 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::REVIEWS_API_PATH),186 EXPECT_CALL(*clientPtr, callImpl(EndsWith(click::REVIEWS_API_PATH),
187 _, _, _, _, _))187 _, _, _, _, _))
@@ -195,7 +195,7 @@
195TEST_F(ReviewsTest, testFetchReviewsCallbackCalled)195TEST_F(ReviewsTest, testFetchReviewsCallbackCalled)
196{196{
197 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;197 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
198 auto response = responseForReply(reply.asSharedPtr());198 auto response = MockClient::responseForReply(reply.asSharedPtr());
199199
200 QByteArray fake_json("[]");200 QByteArray fake_json("[]");
201 EXPECT_CALL(reply.instance, readAll())201 EXPECT_CALL(reply.instance, readAll())
@@ -216,7 +216,7 @@
216TEST_F(ReviewsTest, testFetchReviewsNot200)216TEST_F(ReviewsTest, testFetchReviewsNot200)
217{217{
218 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;218 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
219 auto response = responseForReply(reply.asSharedPtr());219 auto response = MockClient::responseForReply(reply.asSharedPtr());
220220
221 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(301)));221 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(301)));
222 EXPECT_CALL(reply.instance, readAll())222 EXPECT_CALL(reply.instance, readAll())
@@ -238,7 +238,7 @@
238TEST_F(ReviewsTest, testFetchReviewsEmptyJsonIsParsed)238TEST_F(ReviewsTest, testFetchReviewsEmptyJsonIsParsed)
239{239{
240 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;240 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
241 auto response = responseForReply(reply.asSharedPtr());241 auto response = MockClient::responseForReply(reply.asSharedPtr());
242242
243 QByteArray fake_json("[]");243 QByteArray fake_json("[]");
244 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));244 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
@@ -261,7 +261,7 @@
261TEST_F(ReviewsTest, testFetchReviewsSingleJsonIsParsed)261TEST_F(ReviewsTest, testFetchReviewsSingleJsonIsParsed)
262{262{
263 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;263 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
264 auto response = responseForReply(reply.asSharedPtr());264 auto response = MockClient::responseForReply(reply.asSharedPtr());
265265
266 QByteArray fake_json(FAKE_JSON_REVIEWS_RESULT_ONE.c_str());266 QByteArray fake_json(FAKE_JSON_REVIEWS_RESULT_ONE.c_str());
267 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));267 EXPECT_CALL(reply.instance, attribute(_)).WillOnce(Return(QVariant(200)));
@@ -295,7 +295,7 @@
295TEST_F(ReviewsTest, testFetchReviewsNetworkErrorReported)295TEST_F(ReviewsTest, testFetchReviewsNetworkErrorReported)
296{296{
297 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;297 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
298 auto response = responseForReply(reply.asSharedPtr());298 auto response = MockClient::responseForReply(reply.asSharedPtr());
299299
300 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))300 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
301 .Times(1)301 .Times(1)
@@ -318,7 +318,7 @@
318TEST_F(ReviewsTest, testFetchReviewsIsCancellable)318TEST_F(ReviewsTest, testFetchReviewsIsCancellable)
319{319{
320 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;320 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
321 auto response = responseForReply(reply.asSharedPtr());321 auto response = MockClient::responseForReply(reply.asSharedPtr());
322322
323 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))323 EXPECT_CALL(*clientPtr, callImpl(_, _, _, _, _, _))
324 .Times(1)324 .Times(1)
@@ -333,7 +333,7 @@
333TEST_F(ReviewsTest, testSubmitReviewIsCancellable)333TEST_F(ReviewsTest, testSubmitReviewIsCancellable)
334{334{
335 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;335 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
336 auto response = responseForReply(reply.asSharedPtr());336 auto response = MockClient::responseForReply(reply.asSharedPtr());
337337
338 click::Review review;338 click::Review review;
339 review.rating = 3;339 review.rating = 3;
@@ -354,7 +354,7 @@
354TEST_F(ReviewsTest, testSubmitReviewUtf8)354TEST_F(ReviewsTest, testSubmitReviewUtf8)
355{355{
356 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;356 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
357 auto response = responseForReply(reply.asSharedPtr());357 auto response = MockClient::responseForReply(reply.asSharedPtr());
358358
359 click::Review review;359 click::Review review;
360 review.rating = 3;360 review.rating = 3;
@@ -378,7 +378,7 @@
378TEST_F(ReviewsTest, testSubmitReviewLanguageCorrect)378TEST_F(ReviewsTest, testSubmitReviewLanguageCorrect)
379{379{
380 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;380 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
381 auto response = responseForReply(reply.asSharedPtr());381 auto response = MockClient::responseForReply(reply.asSharedPtr());
382382
383 click::Review review;383 click::Review review;
384 review.rating = 3;384 review.rating = 3;
@@ -402,7 +402,7 @@
402TEST_F(ReviewsTest, testSubmitReviewLanguageCorrectForFullLangCodes)402TEST_F(ReviewsTest, testSubmitReviewLanguageCorrectForFullLangCodes)
403{403{
404 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;404 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
405 auto response = responseForReply(reply.asSharedPtr());405 auto response = MockClient::responseForReply(reply.asSharedPtr());
406406
407 click::Review review;407 click::Review review;
408 review.rating = 3;408 review.rating = 3;
@@ -428,7 +428,7 @@
428TEST_F(ReviewsTest, testEditReviewUrlHasReviewId)428TEST_F(ReviewsTest, testEditReviewUrlHasReviewId)
429{429{
430 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;430 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
431 auto response = responseForReply(reply.asSharedPtr());431 auto response = MockClient::responseForReply(reply.asSharedPtr());
432432
433 click::Review review;433 click::Review review;
434 review.id = 1234;434 review.id = 1234;
@@ -448,7 +448,7 @@
448TEST_F(ReviewsTest, testEditReviewIsCancellable)448TEST_F(ReviewsTest, testEditReviewIsCancellable)
449{449{
450 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;450 LifetimeHelper<click::network::Reply, MockNetworkReply> reply;
451 auto response = responseForReply(reply.asSharedPtr());451 auto response = MockClient::responseForReply(reply.asSharedPtr());
452452
453 click::Review review;453 click::Review review;
454 review.id = 1234;454 review.id = 1234;
455455
=== modified file 'scope/clickstore/store-query.cpp'
--- scope/clickstore/store-query.cpp 2016-09-21 14:55:05 +0000
+++ scope/clickstore/store-query.cpp 2016-09-21 14:55:05 +0000
@@ -169,6 +169,7 @@
169 click::HighlightList& highlights;169 click::HighlightList& highlights;
170 scopes::SearchMetadata meta;170 scopes::SearchMetadata meta;
171 click::web::Cancellable search_operation;171 click::web::Cancellable search_operation;
172 click::web::Cancellable search_snaps_operation;
172 click::web::Cancellable purchases_operation;173 click::web::Cancellable purchases_operation;
173 pay::Package& pay_package;174 pay::Package& pay_package;
174 std::shared_future<void> qt_ready_;175 std::shared_future<void> qt_ready_;
@@ -196,6 +197,7 @@
196{197{
197 qDebug() << "cancelling search of" << QString::fromStdString(query().query_string());198 qDebug() << "cancelling search of" << QString::fromStdString(query().query_string());
198 impl->search_operation.cancel();199 impl->search_operation.cancel();
200 impl->search_snaps_operation.cancel();
199}201}
200202
201click::Interface& click::Query::clickInterfaceInstance()203click::Interface& click::Query::clickInterfaceInstance()
@@ -290,7 +292,12 @@
290 res.set_title(pkg.title);292 res.set_title(pkg.title);
291 res.set_art(pkg.icon_url);293 res.set_art(pkg.icon_url);
292 res.set_uri(pkg.url);294 res.set_uri(pkg.url);
293 res[click::Query::ResultKeys::NAME] = pkg.name;295 res["snap_id"] = pkg.snap_id;
296 if (pkg.snap_id.empty()) {
297 res[click::Query::ResultKeys::NAME] = pkg.name;
298 } else {
299 res[click::Query::ResultKeys::NAME] = pkg.alias;
300 }
294 res["subtitle"] = pkg.publisher;301 res["subtitle"] = pkg.publisher;
295 auto installed = installedPackages.find(pkg);302 auto installed = installedPackages.find(pkg);
296303
@@ -533,6 +540,7 @@
533 push_package(searchReply, recommendsCategory,540 push_package(searchReply, recommendsCategory,
534 installedPackages, r);541 installedPackages, r);
535 }542 }
543
536 qDebug() << "search completed";544 qDebug() << "search completed";
537 this->finished(searchReply); //FIXME: this shouldn't be needed545 this->finished(searchReply); //FIXME: this shouldn't be needed
538 };546 };
@@ -596,7 +604,37 @@
596 {604 {
597 qDebug() << "starting search of" << QString::fromStdString(query().query_string());605 qDebug() << "starting search of" << QString::fromStdString(query().query_string());
598 push_departments(searchReply);606 push_departments(searchReply);
599 impl->search_operation = impl->index.search(query().query_string(), query().department_id(), search_cb, force_cache);607 impl->search_operation = impl->index.search
608 (query().query_string(), query().department_id(),
609 [this, search_cb, force_cache](Packages packages,
610 Packages recommends) {
611 if (Configuration().is_snapd_running()) {
612 qDebug() << "Searching for snaps too.";
613 impl->search_snaps_operation = impl->index.search_snaps
614 (query().query_string(),
615 [this, packages, recommends, search_cb](Packages snap_packages,
616 Packages snap_recommends) {
617 qDebug() << "In the callback.";
618 Packages new_packages, new_recommends;
619 for (const auto& p: packages) {
620 new_packages.push_back(p);
621 }
622 for (const auto& p: snap_packages) {
623 new_packages.push_back(p);
624 }
625 for (const auto& r: recommends) {
626 new_recommends.push_back(r);
627 }
628 for (const auto& r: snap_recommends) {
629 new_recommends.push_back(r);
630 }
631 qDebug() << "Snaps appended.";
632 search_cb(new_packages, new_recommends);
633 }, force_cache);
634 } else {
635 search_cb(packages, recommends);
636 }
637 }, force_cache);
600 }638 }
601 }639 }
602 });640 });

Subscribers

People subscribed via source and target branches

to all changes: