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 }