~smoser/ubuntu/trusty/maas/lp-1172566

« back to all changes in this revision

Viewing changes to src/maascli/tests/test_api.py

  • Committer: Package Import Robot
  • Author(s): Andres Rodriguez
  • Date: 2014-04-03 13:45:02 UTC
  • mto: This revision was merged to the branch mainline in revision 58.
  • Revision ID: package-import@ubuntu.com-20140403134502-8a6wvuqwyuekufh0
Tags: upstream-1.5+bzr2227
ImportĀ upstreamĀ versionĀ 1.5+bzr2227

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
__all__ = []
16
16
 
17
17
import collections
 
18
from functools import partial
18
19
import httplib
19
20
import io
20
21
import json
515
516
         {"method": "POST", "data": [],
516
517
          "expected_uri": uri_base,
517
518
          "expected_body": None,
518
 
          "expected_headers": {}}),
 
519
          "expected_headers": []}),
519
520
        ("read",
520
521
         {"method": "GET", "data": [],
521
522
          "expected_uri": uri_base,
522
523
          "expected_body": None,
523
 
          "expected_headers": {}}),
 
524
          "expected_headers": []}),
524
525
        ("update",
525
526
         {"method": "PUT", "data": [],
526
527
          "expected_uri": uri_base,
527
528
          "expected_body": None,
528
 
          "expected_headers": {}}),
 
529
          "expected_headers": []}),
529
530
        ("delete",
530
531
         {"method": "DELETE", "data": [],
531
532
          "expected_uri": uri_base,
532
533
          "expected_body": None,
533
 
          "expected_headers": {}}),
534
 
        # With data, PUT, POST, and DELETE requests have their body and extra
535
 
        # headers prepared by encode_multipart_data. For GET requests, the
536
 
        # data is encoded into the query string, and both the request body and
 
534
          "expected_headers": []}),
 
535
        # With data, PUT, POST, and DELETE requests have their body and
 
536
        # extra headers prepared by build_multipart_message and
 
537
        # encode_multipart_message. For GET requests, the data is
 
538
        # encoded into the query string, and both the request body and
537
539
        # extra headers are empty.
538
540
        ("create-with-data",
539
541
         {"method": "POST", "data": [("foo", "bar"), ("foo", "baz")],
544
546
         {"method": "GET", "data": [("foo", "bar"), ("foo", "baz")],
545
547
          "expected_uri": uri_base + "?foo=bar&foo=baz",
546
548
          "expected_body": None,
547
 
          "expected_headers": {}}),
 
549
          "expected_headers": []}),
548
550
        ("update-with-data",
549
551
         {"method": "PUT", "data": [("foo", "bar"), ("foo", "baz")],
550
552
          "expected_uri": uri_base,
565
567
         {"method": "POST", "data": [],
566
568
          "expected_uri": uri_base + "?op=something",
567
569
          "expected_body": None,
568
 
          "expected_headers": {}}),
 
570
          "expected_headers": []}),
569
571
        ("read",
570
572
         {"method": "GET", "data": [],
571
573
          "expected_uri": uri_base + "?op=something",
572
574
          "expected_body": None,
573
 
          "expected_headers": {}}),
 
575
          "expected_headers": []}),
574
576
        ("update",
575
577
         {"method": "PUT", "data": [],
576
578
          "expected_uri": uri_base + "?op=something",
577
579
          "expected_body": None,
578
 
          "expected_headers": {}}),
 
580
          "expected_headers": []}),
579
581
        ("delete",
580
582
         {"method": "DELETE", "data": [],
581
583
          "expected_uri": uri_base + "?op=something",
582
584
          "expected_body": None,
583
 
          "expected_headers": {}}),
584
 
        # With data, PUT, POST, and DELETE requests have their body and extra
585
 
        # headers prepared by encode_multipart_data. For GET requests, the
586
 
        # data is encoded into the query string, and both the request body and
587
 
        # extra headers are empty. The operation is encoded into the query
588
 
        # string.
 
585
          "expected_headers": []}),
 
586
        # With data, PUT, POST, and DELETE requests have their body and
 
587
        # extra headers prepared by build_multipart_message and
 
588
        # encode_multipart_message. For GET requests, the data is
 
589
        # encoded into the query string, and both the request body and
 
590
        # extra headers are empty. The operation is encoded into the
 
591
        # query string.
589
592
        ("create-with-data",
590
593
         {"method": "POST", "data": [("foo", "bar"), ("foo", "baz")],
591
594
          "expected_uri": uri_base + "?op=something",
595
598
         {"method": "GET", "data": [("foo", "bar"), ("foo", "baz")],
596
599
          "expected_uri": uri_base + "?op=something&foo=bar&foo=baz",
597
600
          "expected_body": None,
598
 
          "expected_headers": {}}),
 
601
          "expected_headers": []}),
599
602
        ("update-with-data",
600
603
         {"method": "PUT", "data": [("foo", "bar"), ("foo", "baz")],
601
604
          "expected_uri": uri_base + "?op=something",
619
622
    scenarios = scenarios_without_op + scenarios_with_op
620
623
 
621
624
    def test_prepare_payload(self):
622
 
        # Patch encode_multipart_data to match the scenarios.
623
 
        encode_multipart_data = self.patch(api, "encode_multipart_data")
624
 
        encode_multipart_data.return_value = sentinel.body, sentinel.headers
 
625
        # Patch build_multipart_message and encode_multipart_message to
 
626
        # match the scenarios.
 
627
        build_multipart_message = self.patch(api, "build_multipart_message")
 
628
        build_multipart_message.return_value = sentinel.message
 
629
        encode_multipart_message = self.patch(api, "encode_multipart_message")
 
630
        encode_multipart_message.return_value = sentinel.headers, sentinel.body
625
631
        # The payload returned is a 3-tuple of (uri, body, headers).
626
632
        payload = api.Action.prepare_payload(
627
633
            op=self.op, method=self.method,
632
638
            Equals(self.expected_headers),
633
639
            )
634
640
        self.assertThat(payload, MatchesListwise(expected))
635
 
        # encode_multipart_data, when called, is passed the data
 
641
        # encode_multipart_message, when called, is passed the data
636
642
        # unadulterated.
637
643
        if self.expected_body is sentinel.body:
638
644
            self.assertThat(
639
 
                api.encode_multipart_data, MockCalledOnceWith(self.data))
 
645
                api.build_multipart_message,
 
646
                MockCalledOnceWith(self.data))
 
647
            self.assertThat(
 
648
                api.encode_multipart_message,
 
649
                MockCalledOnceWith(sentinel.message))
 
650
 
 
651
 
 
652
class TestPayloadPreparationWithFiles(MAASTestCase):
 
653
    """Tests for `maascli.api.Action.prepare_payload` involving files."""
 
654
 
 
655
    def test_files_are_included(self):
 
656
        parameter = factory.make_name("param")
 
657
        contents = factory.getRandomBytes()
 
658
        filename = self.make_file(contents=contents)
 
659
        # Writing the parameter as "parameter@=filename" on the
 
660
        # command-line causes name_value_pair() to return a `name,
 
661
        # opener` tuple, where `opener` is a callable that returns an
 
662
        # open file handle.
 
663
        data = [(parameter, partial(open, filename, "rb"))]
 
664
        uri, body, headers = api.Action.prepare_payload(
 
665
            op=None, method="POST", uri="http://localhost", data=data)
 
666
 
 
667
        expected_body_template = """\
 
668
            --...
 
669
            Content-Transfer-Encoding: base64
 
670
            Content-Disposition: form-data; name="%s"; filename="%s"
 
671
            MIME-Version: 1.0
 
672
            Content-Type: application/octet-stream
 
673
 
 
674
            %s
 
675
            --...--
 
676
            """
 
677
        expected_body = expected_body_template % (
 
678
            parameter, parameter, contents.encode("base64"))
 
679
 
 
680
        self.assertDocTestMatches(expected_body, body)