github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/cmd/juju/romulus/listplans/list_plans_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package listplans_test
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/cmd"
    10  	"github.com/juju/cmd/cmdtesting"
    11  	api "github.com/juju/romulus/api/plan"
    12  	wireformat "github.com/juju/romulus/wireformat/plan"
    13  	"github.com/juju/testing"
    14  	jc "github.com/juju/testing/checkers"
    15  	gc "gopkg.in/check.v1"
    16  	"gopkg.in/macaroon-bakery.v2-unstable/httpbakery"
    17  
    18  	rcmd "github.com/juju/juju/cmd/juju/romulus"
    19  	"github.com/juju/juju/cmd/juju/romulus/listplans"
    20  	"github.com/juju/juju/cmd/modelcmd"
    21  	"github.com/juju/juju/jujuclient"
    22  	coretesting "github.com/juju/juju/testing"
    23  )
    24  
    25  var (
    26  	testPlan1 = `
    27      description:
    28          text: |
    29              Lorem ipsum dolor sit amet,
    30              consectetur adipiscing elit.
    31              Nunc pretium purus nec magna faucibus, sed eleifend dui fermentum. Nulla nec ornare lorem, sed imperdiet turpis. Nam auctor quis massa et commodo. Maecenas in magna erat. Duis non iaculis risus, a malesuada quam. Sed quis commodo sapien. Suspendisse laoreet diam eu interdum tristique. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
    32              Donec eu nunc quis eros fermentum porta non ut justo. Donec ut tempus sapien. Suspendisse bibendum fermentum eros, id feugiat justo elementum quis. Quisque vel volutpat risus. Aenean pellentesque ultrices consequat. Maecenas luctus, augue vitae ullamcorper vulputate, purus ligula accumsan diam, ut efficitur diam tellus ac nibh. Cras eros ligula, mattis in ex quis, porta efficitur quam. Donec porta, est ut interdum blandit, enim est elementum sapien, quis congue orci dui et nulla. Maecenas vehicula malesuada vehicula. Phasellus sapien ante, semper eu ornare sed, vulputate id nunc. Maecenas in orci mollis, sagittis lorem quis, ultrices metus. Integer molestie tempor augue, pulvinar blandit sapien ultricies eget.
    33              Fusce sed tellus sit amet tortor mollis pellentesque. Nulla tempus sem tellus, vitae tempor ipsum scelerisque eu. Cras tempor, tellus nec pretium egestas, felis massa luctus velit, vitae feugiat nunc velit ac tellus. Maecenas quis nisi diam. Sed pulvinar suscipit nibh sit amet cursus. Ut sem orci, consequat id pretium id, lacinia id nisl. Maecenas id quam at nisi eleifend porta. Vestibulum at ligula arcu. Quisque tincidunt pulvinar egestas. Ut suscipit ornare ligula a fermentum. Morbi ante justo, condimentum ut risus vitae, molestie elementum elit. Curabitur malesuada commodo diam sed ultrices. Vestibulum tincidunt turpis at ultricies fermentum. Morbi ipsum felis, laoreet quis risus id, ornare elementum urna. Morbi ultrices porttitor pulvinar. Maecenas facilisis velit sit amet tellus feugiat iaculis.
    34      metrics:
    35        pings:
    36          unit:
    37            transform: max
    38            period: hour
    39            gaps: zero
    40  `
    41  	testPlan2 = `
    42      metrics:
    43        pongs:
    44          unit:
    45            transform: max
    46            period: hour
    47            gaps: zero
    48  `
    49  )
    50  
    51  type ListPlansCommandSuite struct {
    52  	coretesting.FakeJujuXDGDataHomeSuite
    53  	mockAPI *mockapi
    54  	stub    *testing.Stub
    55  }
    56  
    57  var _ = gc.Suite(&ListPlansCommandSuite{})
    58  
    59  func (s *ListPlansCommandSuite) SetUpTest(c *gc.C) {
    60  	s.FakeJujuXDGDataHomeSuite.SetUpTest(c)
    61  	s.stub = &testing.Stub{}
    62  	s.mockAPI = newMockAPI(s.stub)
    63  	s.PatchValue(listplans.NewClient, listplans.APIClientFnc(s.mockAPI))
    64  	s.PatchValue(&rcmd.GetMeteringURLForControllerCmd, func(c *modelcmd.ControllerCommandBase) (string, error) {
    65  		return "http://example.com", nil
    66  	})
    67  }
    68  
    69  func (s *ListPlansCommandSuite) TestTabularOutput(c *gc.C) {
    70  	ctx, err := s.runCommand(c, &mockCharmResolver{
    71  		ResolvedURL: "series/some-charm-url",
    72  		Stub:        s.stub,
    73  	}, "some-charm-url")
    74  	c.Assert(err, jc.ErrorIsNil)
    75  	c.Assert(cmdtesting.Stdout(ctx), gc.Equals,
    76  		`Plan             	Price	Description                                       
    77  bob/test-plan-1  	     	Lorem ipsum dolor sit amet,                       
    78                   	     	consectetur adipiscing elit.                      
    79                   	     	Nunc pretium purus nec magna faucibus, sed        
    80                   	     	eleifend dui fermentum. Nulla nec ornare lorem,   
    81                   	     	sed imperdiet turpis. Nam auctor quis massa et    
    82                   	     	commodo. Maecenas in magna erat. Duis non iaculis 
    83                   	     	risus, a malesuada quam. Sed quis commodo sapien. 
    84                   	     	Suspendisse laoreet diam eu interdum tristique.   
    85                   	     	Class aptent taciti sociosqu ad litora torquent   
    86                   	     	per conubia nostra, per inceptos himenaeos.       
    87                   	     	Donec eu nunc quis eros fermentum porta non ut    
    88                   	     	justo. Donec ut tempus sapien. Suspendisse        
    89                   	     	bibendum fermentum eros, id feugiat justo         
    90                   	     	elementum quis. Quisque vel volutpat risus. Aenean
    91                   	     	pellentesque ultrices consequat. Maecenas luctus, 
    92                   	     	augue vitae ullamcorper vulputate, purus ligula   
    93                   	     	accumsan diam, ut efficitur diam tellus ac nibh.  
    94                   	     	Cras eros ligula, mattis in ex quis, porta        
    95                   	     	efficitur quam. Donec porta, est ut interdum      
    96                   	     	blandit, enim est elementum sapien, quis congue   
    97                   	     	orci dui et nulla. Maecenas vehicula malesuada    
    98                   	     	vehicula. Phasellus sapien ante, semper eu ornare 
    99                   	     	sed, vulputate id nunc. Maecenas in orci mollis,  
   100                   	     	sagittis lorem quis, ultrices metus. Integer      
   101                   	     	molestie tempor augue, pulvinar blandit sapien    
   102                   	     	ultricies eget.                                   
   103                   	     	Fusce sed tellus sit amet tortor mollis           
   104                   	     	pellentesque. Nulla tempus sem tellus, vitae      
   105                   	     	tempor ipsum scelerisque eu. Cras tempor, tellus  
   106                   	     	nec pretium egestas, felis massa luctus velit,    
   107                   	     	vitae feugiat nunc velit ac tellus. Maecenas quis 
   108                   	     	nisi diam. Sed pulvinar suscipit nibh sit amet    
   109                   	     	cursus. Ut sem orci, consequat id pretium id,     
   110                   	     	lacinia id nisl. Maecenas id quam at nisi eleifend
   111                   	     	porta. Vestibulum at ligula arcu. Quisque         
   112                   	     	tincidunt pulvinar egestas. Ut suscipit ornare    
   113                   	     	ligula a fermentum. Morbi ante justo, condimentum 
   114                   	     	ut risus vitae, molestie elementum elit. Curabitur
   115                   	     	malesuada commodo diam sed ultrices. Vestibulum   
   116                   	     	tincidunt turpis at ultricies fermentum. Morbi    
   117                   	     	ipsum felis, laoreet quis risus id, ornare        
   118                   	     	elementum urna. Morbi ultrices porttitor pulvinar.
   119                   	     	Maecenas facilisis velit sit amet tellus feugiat  
   120                   	     	iaculis.                                          
   121                   	     	                                                  
   122  carol/test-plan-2	     	                                                  
   123  `)
   124  }
   125  
   126  func (s *ListPlansCommandSuite) runCommand(c *gc.C, resolver rcmd.CharmResolver, args ...string) (*cmd.Context, error) {
   127  	cleanup := testing.PatchValue(&rcmd.NewCharmStoreResolverForControllerCmd, func(c *modelcmd.ControllerCommandBase) (rcmd.CharmResolver, error) {
   128  		return resolver, nil
   129  	})
   130  	defer cleanup()
   131  	cmd := listplans.NewListPlansCommand()
   132  	cmd.SetClientStore(newMockStore())
   133  	return cmdtesting.RunCommand(c, cmd, args...)
   134  }
   135  
   136  func newMockStore() *jujuclient.MemStore {
   137  	store := jujuclient.NewMemStore()
   138  	store.CurrentControllerName = "foo"
   139  	store.Controllers["foo"] = jujuclient.ControllerDetails{
   140  		APIEndpoints: []string{"0.1.2.3:1234"},
   141  	}
   142  	return store
   143  }
   144  
   145  func (s *ListPlansCommandSuite) TestGetCommands(c *gc.C) {
   146  	tests := []struct {
   147  		about            string
   148  		args             []string
   149  		err              string
   150  		resolvedCharmURL string
   151  		apiCall          []interface{}
   152  	}{{
   153  		about:            "charm url is resolved",
   154  		args:             []string{"some-charm-url"},
   155  		resolvedCharmURL: "series/some-charm-url-1",
   156  		apiCall:          []interface{}{"series/some-charm-url-1"},
   157  	}, {
   158  		about:   "everything works - default format",
   159  		args:    []string{"some-charm-url"},
   160  		apiCall: []interface{}{"some-charm-url"},
   161  	}, {
   162  		about:   "everything works - yaml",
   163  		args:    []string{"some-charm-url", "--format", "yaml"},
   164  		apiCall: []interface{}{"some-charm-url"},
   165  	}, {
   166  		about:   "everything works - smart",
   167  		args:    []string{"some-charm-url", "--format", "smart"},
   168  		apiCall: []interface{}{"some-charm-url"},
   169  	}, {
   170  		about:   "everything works - json",
   171  		args:    []string{"some-charm-url", "--format", "json"},
   172  		apiCall: []interface{}{"some-charm-url"},
   173  	}, {
   174  		about:   "everything works - summary",
   175  		args:    []string{"some-charm-url", "--format", "summary"},
   176  		apiCall: []interface{}{"some-charm-url"},
   177  	}, {
   178  		about:   "everything works - tabular",
   179  		args:    []string{"some-charm-url", "--format", "tabular"},
   180  		apiCall: []interface{}{"some-charm-url"},
   181  	}, {
   182  		about:   "missing argument",
   183  		args:    []string{},
   184  		err:     `missing arguments`,
   185  		apiCall: []interface{}{},
   186  	}, {
   187  		about:   "unknown arguments",
   188  		args:    []string{"some-charm-url", "extra", "arguments"},
   189  		err:     `unknown command line arguments: extra,arguments`,
   190  		apiCall: []interface{}{},
   191  	},
   192  	}
   193  
   194  	for i, t := range tests {
   195  		c.Logf("Running test %d %s", i, t.about)
   196  		s.mockAPI.reset()
   197  
   198  		_, err := s.runCommand(c, &mockCharmResolver{
   199  			ResolvedURL: t.resolvedCharmURL,
   200  			Stub:        s.stub,
   201  		}, t.args...)
   202  		if t.err != "" {
   203  			c.Assert(err, gc.ErrorMatches, t.err)
   204  		} else {
   205  			c.Assert(err, jc.ErrorIsNil)
   206  			s.mockAPI.CheckCall(c, 0, "Resolve", t.args[0])
   207  			s.mockAPI.CheckCall(c, 1, "GetAssociatedPlans", t.apiCall...)
   208  		}
   209  	}
   210  }
   211  
   212  // mockapi mocks the plan service api
   213  type mockapi struct {
   214  	*testing.Stub
   215  	api.Client
   216  }
   217  
   218  func newMockAPI(s *testing.Stub) *mockapi {
   219  	return &mockapi{Stub: s}
   220  }
   221  
   222  // Get implements the Get function of the api.PlanClient interface.
   223  // TODO (domas) : fix once querying by charm url is in place
   224  func (m *mockapi) GetAssociatedPlans(charmURL string) ([]wireformat.Plan, error) {
   225  	m.AddCall("GetAssociatedPlans", charmURL)
   226  	p1 := wireformat.Plan{
   227  		URL:        "bob/test-plan-1",
   228  		Definition: testPlan1,
   229  		CreatedOn:  time.Date(2015, 0, 0, 0, 0, 0, 0, time.UTC).Format(time.RFC3339),
   230  	}
   231  	p2 := wireformat.Plan{
   232  		URL:        "carol/test-plan-2",
   233  		Definition: testPlan2,
   234  		CreatedOn:  time.Date(2015, 0, 0, 0, 0, 0, 0, time.UTC).Format(time.RFC3339),
   235  	}
   236  	return []wireformat.Plan{p1, p2}, m.NextErr()
   237  }
   238  
   239  func (m *mockapi) reset() {
   240  	m.ResetCalls()
   241  }
   242  
   243  // mockCharmResolver is a mock implementation of cmd.CharmResolver.
   244  type mockCharmResolver struct {
   245  	*testing.Stub
   246  	ResolvedURL string
   247  }
   248  
   249  // Resolve implements cmd.CharmResolver.
   250  func (r *mockCharmResolver) Resolve(_ *httpbakery.Client, charmURL string) (string, error) {
   251  	r.AddCall("Resolve", charmURL)
   252  	if r.ResolvedURL != "" {
   253  		return r.ResolvedURL, r.NextErr()
   254  	}
   255  	return charmURL, r.NextErr()
   256  }