github.com/axw/juju@v0.0.0-20161005053422-4bd6544d08d4/cmd/juju/romulus/agree/agree_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package agree_test 5 6 import ( 7 "runtime" 8 "sync" 9 "testing" 10 11 "github.com/juju/cmd/cmdtesting" 12 "github.com/juju/terms-client/api" 13 "github.com/juju/terms-client/api/wireformat" 14 jujutesting "github.com/juju/testing" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 18 "github.com/juju/juju/cmd/juju/romulus/agree" 19 coretesting "github.com/juju/juju/testing" 20 ) 21 22 func TestPackage(t *testing.T) { 23 gc.TestingT(t) 24 } 25 26 var _ = gc.Suite(&agreeSuite{}) 27 28 var testTerms = "Test Terms" 29 30 type agreeSuite struct { 31 client *mockClient 32 coretesting.FakeJujuXDGDataHomeSuite 33 } 34 35 func (s *agreeSuite) SetUpTest(c *gc.C) { 36 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 37 s.client = &mockClient{} 38 39 jujutesting.PatchValue(agree.ClientNew, func(...api.ClientOption) (api.Client, error) { 40 return s.client, nil 41 }) 42 } 43 44 func (s *agreeSuite) TestAgreementNothingToSign(c *gc.C) { 45 jujutesting.PatchValue(agree.UserAnswer, func() (string, error) { 46 return "y", nil 47 }) 48 49 s.client.user = "test-user" 50 s.client.setUnsignedTerms([]wireformat.GetTermsResponse{}) 51 52 ctx, err := cmdtesting.RunCommand(c, agree.NewAgreeCommand(), "test-term/1") 53 c.Assert(err, jc.ErrorIsNil) 54 c.Assert(cmdtesting.Stdout(ctx), gc.Equals, `Already agreed 55 `) 56 } 57 58 func (s *agreeSuite) TestAgreement(c *gc.C) { 59 if runtime.GOOS == "windows" { 60 c.Skip("less not on windows, bug 1614330") 61 } 62 var answer string 63 jujutesting.PatchValue(agree.UserAnswer, func() (string, error) { 64 return answer, nil 65 }) 66 67 s.client.user = "test-user" 68 s.client.setUnsignedTerms([]wireformat.GetTermsResponse{{ 69 Name: "test-term", 70 Revision: 1, 71 Content: testTerms, 72 }}) 73 tests := []struct { 74 about string 75 args []string 76 err string 77 stdout string 78 answer string 79 apiCalls []jujutesting.StubCall 80 clientTerms []wireformat.GetTermsResponse 81 }{{ 82 about: "everything works", 83 args: []string{"test-term/1", "--yes"}, 84 stdout: "Agreed to revision 1 of test-term for Juju users\n", 85 apiCalls: []jujutesting.StubCall{{FuncName: "SaveAgreement", Args: []interface{}{&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermName: "test-term", TermRevision: 1}}}}}}, 86 }, { 87 about: "everything works with owner term", 88 args: []string{"owner/test-term/1", "--yes"}, 89 stdout: "Agreed to revision 1 of owner/test-term for Juju users\n", 90 apiCalls: []jujutesting.StubCall{{FuncName: "SaveAgreement", Args: []interface{}{&wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermOwner: "owner", TermName: "test-term", TermRevision: 1}}}}}}, 91 }, { 92 about: "cannot parse revision number", 93 args: []string{"test-term/abc"}, 94 err: `must specify a valid term revision "test-term/abc"`, 95 }, { 96 about: "missing arguments", 97 args: []string{}, 98 err: "missing arguments", 99 }, { 100 about: "everything works - user accepts", 101 args: []string{"test-term/1"}, 102 answer: "y", 103 stdout: ` 104 === test-term/1: 0001-01-01 00:00:00 +0000 UTC === 105 Test Terms 106 ======== 107 Do you agree to the displayed terms? (Y/n): Agreed to revision 1 of test-term for Juju users 108 `, 109 apiCalls: []jujutesting.StubCall{{ 110 FuncName: "GetUnunsignedTerms", Args: []interface{}{ 111 &wireformat.CheckAgreementsRequest{Terms: []string{"test-term/1"}}, 112 }, 113 }, { 114 FuncName: "SaveAgreement", Args: []interface{}{ 115 &wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermName: "test-term", TermRevision: 1}}}, 116 }, 117 }}, 118 }, { 119 about: "everything works - user refuses", 120 args: []string{"test-term/1"}, 121 answer: "n", 122 stdout: ` 123 === test-term/1: 0001-01-01 00:00:00 +0000 UTC === 124 Test Terms 125 ======== 126 Do you agree to the displayed terms? (Y/n): You didn't agree to the presented terms. 127 `, 128 apiCalls: []jujutesting.StubCall{{ 129 FuncName: "GetUnunsignedTerms", Args: []interface{}{ 130 &wireformat.CheckAgreementsRequest{Terms: []string{"test-term/1"}}, 131 }, 132 }}, 133 }, { 134 about: "must not accept 0 revision", 135 args: []string{"test-term/0", "--yes"}, 136 err: `must specify a valid term revision "test-term/0"`, 137 }, { 138 about: "user accepts, multiple terms", 139 args: []string{"test-term/1", "test-term/2"}, 140 answer: "y", 141 stdout: ` 142 === test-term/1: 0001-01-01 00:00:00 +0000 UTC === 143 Test Terms 144 ======== 145 Do you agree to the displayed terms? (Y/n): Agreed to revision 1 of test-term for Juju users 146 `, 147 apiCalls: []jujutesting.StubCall{ 148 { 149 FuncName: "GetUnunsignedTerms", Args: []interface{}{ 150 &wireformat.CheckAgreementsRequest{Terms: []string{"test-term/1", "test-term/2"}}, 151 }, 152 }, { 153 FuncName: "SaveAgreement", Args: []interface{}{ 154 &wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{ 155 {TermName: "test-term", TermRevision: 1}, 156 }}, 157 }, 158 }}, 159 }, { 160 about: "valid then unknown arguments", 161 args: []string{"test-term/1", "unknown", "arguments"}, 162 err: `must specify a valid term revision "unknown"`, 163 }, { 164 about: "user accepts all the terms", 165 args: []string{"test-term/1", "test-term/2", "--yes"}, 166 stdout: `Agreed to revision 1 of test-term for Juju users 167 Agreed to revision 2 of test-term for Juju users 168 `, 169 apiCalls: []jujutesting.StubCall{ 170 {FuncName: "SaveAgreement", Args: []interface{}{&wireformat.SaveAgreements{ 171 Agreements: []wireformat.SaveAgreement{ 172 {TermName: "test-term", TermRevision: 1}, 173 {TermName: "test-term", TermRevision: 2}, 174 }}}}}, 175 }, { 176 about: "everything works with term owner - user accepts", 177 clientTerms: []wireformat.GetTermsResponse{{ 178 Name: "test-term", 179 Owner: "test-owner", 180 Revision: 1, 181 Content: testTerms, 182 }}, 183 args: []string{"test-owner/test-term/1"}, 184 answer: "y", 185 stdout: ` 186 === test-owner/test-term/1: 0001-01-01 00:00:00 +0000 UTC === 187 Test Terms 188 ======== 189 Do you agree to the displayed terms? (Y/n): Agreed to revision 1 of test-owner/test-term for Juju users 190 `, 191 apiCalls: []jujutesting.StubCall{{ 192 FuncName: "GetUnunsignedTerms", Args: []interface{}{ 193 &wireformat.CheckAgreementsRequest{Terms: []string{"test-owner/test-term/1"}}, 194 }, 195 }, { 196 FuncName: "SaveAgreement", Args: []interface{}{ 197 &wireformat.SaveAgreements{Agreements: []wireformat.SaveAgreement{{TermOwner: "test-owner", TermName: "test-term", TermRevision: 1}}}, 198 }, 199 }}, 200 }} 201 for i, test := range tests { 202 s.client.ResetCalls() 203 if len(test.clientTerms) > 0 { 204 s.client.setUnsignedTerms(test.clientTerms) 205 } 206 c.Logf("running test %d: %s", i, test.about) 207 if test.answer != "" { 208 answer = test.answer 209 } 210 ctx, err := cmdtesting.RunCommand(c, agree.NewAgreeCommand(), test.args...) 211 if test.err != "" { 212 c.Assert(err, gc.ErrorMatches, test.err) 213 } else { 214 c.Assert(err, jc.ErrorIsNil) 215 } 216 if ctx != nil { 217 c.Assert(cmdtesting.Stdout(ctx), gc.Equals, test.stdout) 218 } 219 if len(test.apiCalls) > 0 { 220 s.client.CheckCalls(c, test.apiCalls) 221 } 222 } 223 } 224 225 type mockClient struct { 226 api.Client 227 jujutesting.Stub 228 229 lock sync.Mutex 230 user string 231 terms []wireformat.GetTermsResponse 232 unsignedTerms []wireformat.GetTermsResponse 233 } 234 235 func (c *mockClient) setUnsignedTerms(t []wireformat.GetTermsResponse) { 236 c.lock.Lock() 237 defer c.lock.Unlock() 238 c.unsignedTerms = t 239 } 240 241 // SaveAgreement saves user's agreement to the specified 242 // revision of the terms documents 243 func (c *mockClient) SaveAgreement(p *wireformat.SaveAgreements) (*wireformat.SaveAgreementResponses, error) { 244 c.AddCall("SaveAgreement", p) 245 responses := make([]wireformat.AgreementResponse, len(p.Agreements)) 246 for i, agreement := range p.Agreements { 247 responses[i] = wireformat.AgreementResponse{ 248 User: c.user, 249 Owner: agreement.TermOwner, 250 Term: agreement.TermName, 251 Revision: agreement.TermRevision, 252 } 253 } 254 return &wireformat.SaveAgreementResponses{responses}, nil 255 } 256 257 func (c *mockClient) GetUnsignedTerms(p *wireformat.CheckAgreementsRequest) ([]wireformat.GetTermsResponse, error) { 258 c.MethodCall(c, "GetUnunsignedTerms", p) 259 r := make([]wireformat.GetTermsResponse, len(c.unsignedTerms)) 260 copy(r, c.unsignedTerms) 261 return r, nil 262 } 263 264 func (c *mockClient) GetUsersAgreements() ([]wireformat.AgreementResponse, error) { 265 c.MethodCall(c, "GetUsersAgreements") 266 return []wireformat.AgreementResponse{}, nil 267 }