def test_initialization(self):
        """Test whether attributes are initializated"""

        launchpad = Launchpad('mydistribution', tag='test')
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.package, None)
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'test')
        self.assertIsNone(launchpad.client)

        launchpad = Launchpad('mydistribution',
                              tag='test',
                              package="mypackage")
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.package, 'mypackage')
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'test')

        # When tag is empty or None it will be set to
        # the value in origin
        launchpad = Launchpad('mydistribution', tag=None)
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'https://launchpad.net/mydistribution')

        launchpad = Launchpad('mydistribution', tag='')
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'https://launchpad.net/mydistribution')
    def test_fetch_empty_no_package_from_archive(self):
        """Test when no issues are returned from an empty archive"""

        empty_issues = read_file('data/launchpad/launchpad_empty_issues')
        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_DISTRIBUTION_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&ws.start=0",
            body=empty_issues,
            status=200)

        self.backend_write_archive = Launchpad('mydistribution',
                                               items_per_page=2,
                                               archive=self.archive)
        self.backend_read_archive = Launchpad('mydistribution',
                                              items_per_page=2,
                                              archive=self.archive)

        self._test_fetch_from_archive()
Beispiel #3
0
    def test_fetch_empty_no_package(self):
        """Test when no issues are available"""

        empty_issues = read_file('data/launchpad/launchpad_empty_issues')
        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_DISTRIBUTION_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&ws.start=0",
            body=empty_issues,
            status=200)

        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              items_per_page=2)
        issues = [issues for issues in launchpad.fetch()]

        self.assertListEqual(issues, [])
Beispiel #4
0
    def test_fetch_from_cache_no_entries(self):
        """Test when activities, attachments and messages contain no JSON-like data"""

        issues_page_1 = read_file(
            'data/launchpad/launchpad_issues_page_1_no_entries')
        issue_1 = read_file('data/launchpad/launchpad_issue_1_no_entries')
        issue_1_comments = read_file(
            'data/launchpad/launchpad_issue_1_comments_no_entries')
        issue_1_attachments = read_file(
            'data/launchpad/launchpad_issue_1_attachments_no_entries')
        issue_1_activities = read_file(
            'data/launchpad/launchpad_issue_1_activities_no_entries')

        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1",
            body=issues_page_1,
            status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1",
                               body=issue_1,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/messages",
                               body=issue_1_comments,
                               status=410)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/attachments",
                               body=issue_1_attachments,
                               status=410)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/activity",
                               body=issue_1_activities,
                               status=410)

        cache = Cache(self.tmp_path)
        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              package='mypackage',
                              items_per_page=2,
                              cache=cache)
        issues = [issues for issues in launchpad.fetch()]

        issues_from_cache = [issues for issues in launchpad.fetch_from_cache()]

        self.assertDictEqual(issues[0]['data'], issues_from_cache[0]['data'])
 def setUp(self):
     super().setUp()
     self.backend_write_archive = Launchpad('mydistribution',
                                            package="mypackage",
                                            items_per_page=2,
                                            archive=self.archive)
     self.backend_read_archive = Launchpad('mydistribution',
                                           package="mypackage",
                                           items_per_page=2,
                                           archive=self.archive)
Beispiel #6
0
    def test_fetch_from_non_set_cache(self):
        """Test if a error is raised when the cache was not set"""

        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              package="mypackage")

        with self.assertRaises(CacheError):
            _ = [cache_issues for cache_issues in launchpad.fetch_from_cache()]
Beispiel #7
0
    def test_fetch_from_date(self):
        """Test when return from date"""

        issues_page_1 = read_file('data/launchpad/launchpad_issues_page_1_no_next')
        issue_1 = read_file('data/launchpad/launchpad_issue_1')
        issue_1_comments = read_file('data/launchpad/launchpad_issue_1_comments')
        issue_1_attachments = read_file('data/launchpad/launchpad_issue_1_attachments')
        issue_1_activities = read_file('data/launchpad/launchpad_issue_1_activities')
        user_1 = read_file('data/launchpad/launchpad_user_1')
        issue_1_expected = read_file('data/launchpad/launchpad_issue_1_expected')

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_PACKAGE_PROJECT_URL +
                               "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
                               "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
                               "&status=Fix+Committed&status=Fix+Released"
                               "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
                               "&status=Incomplete+%28without+response%29"
                               "&status=Invalid&status=New&status=Opinion&status=Triaged"
                               "&status=Won%27t+Fix"
                               "&ws.size=1",
                               body=issues_page_1,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1",
                               body=issue_1,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/messages",
                               body=issue_1_comments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/attachments",
                               body=issue_1_attachments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/activity",
                               body=issue_1_activities,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/~user",
                               body=user_1,
                               status=200)

        launchpad = Launchpad('mydistribution', package="mypackage", items_per_page=2)
        from_date = datetime.datetime(2018, 8, 21, 16, 0, 0)
        issues = [issues for issues in launchpad.fetch(from_date=from_date)]
        issue_1_expected = json.loads(issue_1_expected)

        self.assertEqual(len(issues), 1)
        self.assertDictEqual(issues[0]['data'], issue_1_expected)
Beispiel #8
0
    def test_fetch_from_empty_cache(self):
        """Test if there are not any issues returned when the cache is empty"""

        cache = Cache(self.tmp_path)
        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              package="mypackage",
                              cache=cache)

        cache_issues = [
            cache_issues for cache_issues in launchpad.fetch_from_cache()
        ]

        self.assertEqual(len(cache_issues), 0)
Beispiel #9
0
    def test_initialization(self):
        """Test whether attributes are initializated"""

        launchpad = Launchpad('mydistribution', tag='test')
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.package, None)
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'test')

        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              tag='test',
                              package="mypackage")
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.package, 'mypackage')
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'test')

        # When tag is empty or None it will be set to
        # the value in origin
        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              tag=None)
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'https://launchpad.net/mydistribution')

        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              tag='')
        self.assertEqual(launchpad.distribution, 'mydistribution')
        self.assertEqual(launchpad.origin,
                         'https://launchpad.net/mydistribution')
        self.assertEqual(launchpad.tag, 'https://launchpad.net/mydistribution')
    def test_has_resuming(self):
        """Test if it returns True when has_resuming is called"""

        self.assertEqual(Launchpad.has_resuming(), True)
    def test_has_archiving(self):
        """Test if it returns False when has_archiving is called"""

        self.assertEqual(Launchpad.has_archiving(), True)
    def test_fetch(self):
        """Test whether a list of issues is returned"""

        issues_page_1 = read_file('data/launchpad/launchpad_issues_page_1')
        issues_page_2 = read_file('data/launchpad/launchpad_issues_page_2')
        issues_page_3 = read_file('data/launchpad/launchpad_issues_page_3')

        issue_1 = read_file('data/launchpad/launchpad_issue_1')
        issue_2 = read_file('data/launchpad/launchpad_issue_2')
        issue_3 = read_file('data/launchpad/launchpad_issue_3')

        issue_1_comments = read_file(
            'data/launchpad/launchpad_issue_1_comments')
        issue_1_attachments = read_file(
            'data/launchpad/launchpad_issue_1_attachments')
        issue_1_activities = read_file(
            'data/launchpad/launchpad_issue_1_activities')

        issue_2_activities = read_file(
            'data/launchpad/launchpad_issue_2_activities')
        issue_2_comments = read_file(
            'data/launchpad/launchpad_issue_2_comments')

        user_1 = read_file('data/launchpad/launchpad_user_1')

        empty_issue_comments = read_file(
            'data/launchpad/launchpad_empty_issue_comments')
        empty_issue_attachments = read_file(
            'data/launchpad/launchpad_empty_issue_attachments')
        empty_issue_activities = read_file(
            'data/launchpad/launchpad_empty_issue_activities')

        issue_1_expected = read_file(
            'data/launchpad/launchpad_issue_1_expected')
        issue_2_expected = read_file(
            'data/launchpad/launchpad_issue_2_expected')
        issue_3_expected = read_file(
            'data/launchpad/launchpad_issue_3_expected')

        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&memo=2&ws.start=2",
            body=issues_page_3,
            status=200)
        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&memo=1&ws.start=1",
            body=issues_page_2,
            status=200)
        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1",
            body=issues_page_1,
            status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1",
                               body=issue_1,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2",
                               body=issue_2,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3",
                               body=issue_3,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/messages",
                               body=issue_1_comments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2/messages",
                               body=issue_2_comments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3/messages",
                               body=empty_issue_comments,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/attachments",
                               body=issue_1_attachments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2/attachments",
                               body=empty_issue_attachments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3/attachments",
                               body=empty_issue_attachments,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/activity",
                               body=issue_1_activities,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2/activity",
                               body=issue_2_activities,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3/activity",
                               body=empty_issue_activities,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/~user",
                               body=user_1,
                               status=200)

        launchpad = Launchpad('mydistribution',
                              package="mypackage",
                              items_per_page=2)
        issues = [issues for issues in launchpad.fetch(from_date=None)]

        issue_1_expected = json.loads(issue_1_expected)
        issue_2_expected = json.loads(issue_2_expected)
        issue_3_expected = json.loads(issue_3_expected)

        self.assertEqual(len(issues), 3)
        self.assertEqual(len(issues[0]['data']['activity_data']), 1)
        self.assertEqual(len(issues[0]['data']['messages_data']), 2)
        self.assertDictEqual(issues[0]['data']['assignee_data'],
                             issue_1_expected['assignee_data'])
        self.assertDictEqual(issues[0]['data']['owner_data'],
                             issue_1_expected['owner_data'])
        self.assertListEqual(issues[0]['data']['activity_data'],
                             issue_1_expected['activity_data'])
        self.assertListEqual(issues[0]['data']['messages_data'],
                             issue_1_expected['messages_data'])
        self.assertDictEqual(issues[0]['data'], issue_1_expected)

        self.assertDictEqual(issues[1]['data']['assignee_data'],
                             issue_2_expected['assignee_data'])
        self.assertDictEqual(issues[1]['data']['owner_data'],
                             issue_2_expected['owner_data'])
        self.assertEqual(len(issues[1]['data']['activity_data']), 1)
        self.assertEqual(len(issues[1]['data']['messages_data']), 1)
        self.assertListEqual(issues[1]['data']['activity_data'],
                             issue_2_expected['activity_data'])
        self.assertListEqual(issues[1]['data']['messages_data'],
                             issue_2_expected['messages_data'])
        self.assertDictEqual(issues[1]['data'], issue_2_expected)

        self.assertDictEqual(issues[2]['data']['assignee_data'],
                             issue_3_expected['assignee_data'])
        self.assertDictEqual(issues[2]['data']['owner_data'],
                             issue_3_expected['owner_data'])
        self.assertEqual(len(issues[2]['data']['activity_data']), 0)
        self.assertEqual(len(issues[2]['data']['messages_data']), 0)
        self.assertListEqual(issues[2]['data']['activity_data'],
                             issue_3_expected['activity_data'])
        self.assertListEqual(issues[2]['data']['messages_data'],
                             issue_3_expected['messages_data'])
        self.assertDictEqual(issues[2]['data'], issue_3_expected)
Beispiel #13
0
parser.add_argument("-C",
                    "--use-created-date",
                    help="Use created date instead of update date",
                    type=lambda s: s.lower() in ['true', 't', 'yes', 'y', '1'])
parser.add_argument("-D",
                    "--updated-diff",
                    help="If >=0 skip objects where created + diff > updated",
                    type=int,
                    default=-1)
args = parser.parse_args()
# print(args)
# print ((args.date_from, args.date_to))

lp = Launchpad(args.distribution,
               package=args.package,
               items_per_page=75,
               sleep_time=300,
               tag=None,
               archive=None)
# print(lp)

oids = set()
for issue in lp.fetch(category=args.category, from_date=args.date_from):
    # print(issue)
    # print(issue.keys())
    # print(issue['data'].keys())
    # print(issue['data']['bug_data'].keys())
    # dtu = dateutil.parser.parse(issue['data']['bug_data']['date_last_updated'])
    dtu = utc.localize(
        datetime.datetime.fromtimestamp(lp.metadata_updated_on(issue['data'])))
    # print(dtu)
    if args.use_created_date:
Beispiel #14
0
#! /usr/bin/env python3

from datetime import datetime, timedelta
from perceval.backends.core.launchpad import Launchpad
from pprint import pprint

# name
name = "ubuntu"
# retrieve only reviews changed since one day ago
from_date = datetime.now() - timedelta(days=1)

repo = Launchpad(name)

# fetch all reviews as an iterator, and iterate it printing each review id
# for review in repo.fetch(from_date=from_date):
#     pprint(review)

for review in repo.fetch(from_date=from_date):
    print(review['data']['activity_data'][0]['person_data']['display_name'])
Beispiel #15
0
    def test_fetch_from_cache(self):
        """Test whether a list of issues is returned from cache"""

        issues_page_1 = read_file('data/launchpad/launchpad_issues_page_1')
        issues_page_2 = read_file('data/launchpad/launchpad_issues_page_2')
        issues_page_3 = read_file('data/launchpad/launchpad_issues_page_3')

        issue_1 = read_file('data/launchpad/launchpad_issue_1')
        issue_2 = read_file('data/launchpad/launchpad_issue_2')
        issue_3 = read_file('data/launchpad/launchpad_issue_3')

        issue_1_activities_next_1 = read_file(
            'data/launchpad/launchpad_issue_1_activities_next_1')
        issue_1_activities_next_2 = read_file(
            'data/launchpad/launchpad_issue_1_activities_next_2')

        issue_1_comments_next_1 = read_file(
            'data/launchpad/launchpad_issue_1_comments_next_1')
        issue_1_comments_next_2 = read_file(
            'data/launchpad/launchpad_issue_1_comments_next_2')

        issue_1_attachments_next_1 = \
            read_file('data/launchpad/launchpad_issue_1_attachments_next_1')
        issue_1_attachments_next_2 = \
            read_file('data/launchpad/launchpad_issue_1_attachments_next_2')

        issue_2_activities = read_file(
            'data/launchpad/launchpad_issue_2_activities')
        issue_2_comments = read_file(
            'data/launchpad/launchpad_issue_2_comments')

        user_1 = read_file('data/launchpad/launchpad_user_1')

        empty_issue_comments = read_file(
            'data/launchpad/launchpad_empty_issue_comments')
        empty_issue_attachments = read_file(
            'data/launchpad/launchpad_empty_issue_attachments')
        empty_issue_activities = read_file(
            'data/launchpad/launchpad_empty_issue_activities')

        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&memo=2&ws.start=2",
            body=issues_page_3,
            status=200)
        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&memo=1&ws.start=1",
            body=issues_page_2,
            status=200)
        httpretty.register_uri(
            httpretty.GET,
            LAUNCHPAD_PACKAGE_PROJECT_URL +
            "?modified_since=1970-01-01T00%3A00%3A00%2B00%3A00&ws.op=searchTasks"
            "&omit_duplicates=false&order_by=date_last_updated&status=Confirmed&status=Expired"
            "&status=Fix+Committed&status=Fix+Released"
            "&status=In+Progress&status=Incomplete&status=Incomplete+%28with+response%29"
            "&status=Incomplete+%28without+response%29"
            "&status=Invalid&status=New&status=Opinion&status=Triaged"
            "&status=Won%27t+Fix"
            "&ws.size=1&ws.start=0",
            body=issues_page_1,
            status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1",
                               body=issue_1,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2",
                               body=issue_2,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3",
                               body=issue_3,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/messages",
                               body=issue_1_comments_next_2,
                               params={
                                   'ws.size': 2,
                                   'memo': 2,
                                   'ws.start': 2
                               },
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/messages",
                               body=issue_1_comments_next_1,
                               params={
                                   'ws.size': 2,
                                   'orderby': '-datecreated',
                                   'ws.start': 0
                               },
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2/messages",
                               body=issue_2_comments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3/messages",
                               body=empty_issue_comments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/attachments",
                               body=issue_1_attachments_next_2,
                               params={
                                   'orderby': '-datecreated',
                                   'ws.size': 2,
                                   'memo': 2,
                                   'ws.start': 2
                               },
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/attachments",
                               body=issue_1_attachments_next_1,
                               params={
                                   'orderby': '-datecreated',
                                   'ws.size': 2,
                                   'ws.start': 0
                               },
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2/attachments",
                               body=empty_issue_attachments,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3/attachments",
                               body=empty_issue_attachments,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/activity",
                               body=issue_1_activities_next_2,
                               params={
                                   'orderby': '-datecreated',
                                   'ws.size': 2,
                                   'memo': 2,
                                   'ws.start': 2
                               },
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/1/activity",
                               body=issue_1_activities_next_1,
                               params={
                                   'orderby': '-datecreated',
                                   'ws.size': 2,
                                   'ws.start': 0
                               },
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/2/activity",
                               body=issue_2_activities,
                               status=200)
        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/bugs/3/activity",
                               body=empty_issue_activities,
                               status=200)

        httpretty.register_uri(httpretty.GET,
                               LAUNCHPAD_API_URL + "/~user",
                               body=user_1,
                               status=200)

        # First, we fetch the bugs from the server and store them in a cache
        cache = Cache(self.tmp_path)
        launchpad = Launchpad('mydistribution',
                              consumer_key=CONSUMER_KEY,
                              api_token=OAUTH_TOKEN,
                              package="mypackage",
                              cache=cache,
                              items_per_page=2)
        issues = [issues for issues in launchpad.fetch()]

        # Now, we get the bugs from the cache.
        cache_issues = [
            cache_issues for cache_issues in launchpad.fetch_from_cache()
        ]

        del issues[0]['timestamp']
        del cache_issues[0]['timestamp']
        del issues[1]['timestamp']
        del cache_issues[1]['timestamp']
        del issues[2]['timestamp']
        del cache_issues[2]['timestamp']

        self.assertEqual(len(issues), len(cache_issues))
        self.assertDictEqual(issues[0], cache_issues[0])
        self.assertDictEqual(issues[1], cache_issues[1])
        self.assertDictEqual(issues[2], cache_issues[2])