github.com/anonymouse64/snapd@v0.0.0-20210824153203-04c4c42d842d/daemon/api_buy_unsupp_test.go (about) 1 /* 2 * Copyright (C) 2014-2020 Canonical Ltd 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 3 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. 15 * 16 */ 17 18 package daemon_test 19 20 import ( 21 "bytes" 22 "fmt" 23 "net/http" 24 25 "gopkg.in/check.v1" 26 27 "github.com/snapcore/snapd/client" 28 "github.com/snapcore/snapd/daemon" 29 "github.com/snapcore/snapd/overlord/auth" 30 "github.com/snapcore/snapd/store" 31 ) 32 33 var _ = check.Suite(&buySuite{}) 34 35 type buySuite struct { 36 apiBaseSuite 37 38 user *auth.UserState 39 err error 40 41 buyOptions *client.BuyOptions 42 buyResult *client.BuyResult 43 } 44 45 func (s *buySuite) Buy(options *client.BuyOptions, user *auth.UserState) (*client.BuyResult, error) { 46 s.pokeStateLock() 47 48 s.buyOptions = options 49 s.user = user 50 return s.buyResult, s.err 51 } 52 53 func (s *buySuite) ReadyToBuy(user *auth.UserState) error { 54 s.pokeStateLock() 55 56 s.user = user 57 return s.err 58 } 59 60 func (s *buySuite) SetUpTest(c *check.C) { 61 s.apiBaseSuite.SetUpTest(c) 62 63 s.user = nil 64 s.err = nil 65 s.buyOptions = nil 66 s.buyResult = nil 67 68 s.daemonWithStore(c, s) 69 70 s.expectAuthenticatedAccess() 71 } 72 73 const validBuyInput = `{ 74 "snap-id": "the-snap-id-1234abcd", 75 "snap-name": "the snap name", 76 "price": 1.23, 77 "currency": "EUR" 78 }` 79 80 var validBuyOptions = &client.BuyOptions{ 81 SnapID: "the-snap-id-1234abcd", 82 Price: 1.23, 83 Currency: "EUR", 84 } 85 86 var buyTests = []struct { 87 input string 88 result *client.BuyResult 89 err error 90 expectedStatus int 91 expectedResult interface{} 92 expectedResponseType daemon.ResponseType 93 expectedBuyOptions *client.BuyOptions 94 }{ 95 { 96 // Success 97 input: validBuyInput, 98 result: &client.BuyResult{ 99 State: "Complete", 100 }, 101 expectedStatus: 200, 102 expectedResult: &client.BuyResult{ 103 State: "Complete", 104 }, 105 expectedResponseType: daemon.ResponseTypeSync, 106 expectedBuyOptions: validBuyOptions, 107 }, 108 { 109 // Fail with internal error 110 input: `{ 111 "snap-id": "the-snap-id-1234abcd", 112 "price": 1.23, 113 "currency": "EUR" 114 }`, 115 err: fmt.Errorf("internal error banana"), 116 expectedStatus: 500, 117 expectedResponseType: daemon.ResponseTypeError, 118 expectedResult: &daemon.ErrorResult{ 119 Message: "internal error banana", 120 }, 121 expectedBuyOptions: &client.BuyOptions{ 122 SnapID: "the-snap-id-1234abcd", 123 Price: 1.23, 124 Currency: "EUR", 125 }, 126 }, 127 { 128 // Fail with unauthenticated error 129 input: validBuyInput, 130 err: store.ErrUnauthenticated, 131 expectedStatus: 400, 132 expectedResponseType: daemon.ResponseTypeError, 133 expectedResult: &daemon.ErrorResult{ 134 Message: "you need to log in first", 135 Kind: "login-required", 136 }, 137 expectedBuyOptions: validBuyOptions, 138 }, 139 { 140 // Fail with TOS not accepted 141 input: validBuyInput, 142 err: store.ErrTOSNotAccepted, 143 expectedStatus: 400, 144 expectedResponseType: daemon.ResponseTypeError, 145 expectedResult: &daemon.ErrorResult{ 146 Message: "terms of service not accepted", 147 Kind: "terms-not-accepted", 148 }, 149 expectedBuyOptions: validBuyOptions, 150 }, 151 { 152 // Fail with no payment methods 153 input: validBuyInput, 154 err: store.ErrNoPaymentMethods, 155 expectedStatus: 400, 156 expectedResponseType: daemon.ResponseTypeError, 157 expectedResult: &daemon.ErrorResult{ 158 Message: "no payment methods", 159 Kind: "no-payment-methods", 160 }, 161 expectedBuyOptions: validBuyOptions, 162 }, 163 { 164 // Fail with payment declined 165 input: validBuyInput, 166 err: store.ErrPaymentDeclined, 167 expectedStatus: 400, 168 expectedResponseType: daemon.ResponseTypeError, 169 expectedResult: &daemon.ErrorResult{ 170 Message: "payment declined", 171 Kind: "payment-declined", 172 }, 173 expectedBuyOptions: validBuyOptions, 174 }, 175 } 176 177 func (s *buySuite) TestBuySnap(c *check.C) { 178 user := &auth.UserState{ 179 Username: "username", 180 Email: "email@test.com", 181 } 182 183 for _, test := range buyTests { 184 s.buyResult = test.result 185 s.err = test.err 186 187 buf := bytes.NewBufferString(test.input) 188 req, err := http.NewRequest("POST", "/v2/buy", buf) 189 c.Assert(err, check.IsNil) 190 191 rsp := s.jsonReq(c, req, user) 192 193 c.Check(rsp.Status, check.Equals, test.expectedStatus) 194 c.Check(rsp.Type, check.Equals, test.expectedResponseType) 195 c.Assert(rsp.Result, check.FitsTypeOf, test.expectedResult) 196 c.Check(rsp.Result, check.DeepEquals, test.expectedResult) 197 198 c.Check(s.buyOptions, check.DeepEquals, test.expectedBuyOptions) 199 c.Check(s.user, check.Equals, user) 200 } 201 } 202 203 var readyToBuyTests = []struct { 204 input error 205 status int 206 respType interface{} 207 response interface{} 208 }{ 209 { 210 // Success 211 input: nil, 212 status: 200, 213 respType: daemon.ResponseTypeSync, 214 response: true, 215 }, 216 { 217 // Not accepted TOS 218 input: store.ErrTOSNotAccepted, 219 status: 400, 220 respType: daemon.ResponseTypeError, 221 response: &daemon.ErrorResult{ 222 Message: "terms of service not accepted", 223 Kind: client.ErrorKindTermsNotAccepted, 224 }, 225 }, 226 { 227 // No payment methods 228 input: store.ErrNoPaymentMethods, 229 status: 400, 230 respType: daemon.ResponseTypeError, 231 response: &daemon.ErrorResult{ 232 Message: "no payment methods", 233 Kind: client.ErrorKindNoPaymentMethods, 234 }, 235 }, 236 } 237 238 func (s *buySuite) TestReadyToBuy(c *check.C) { 239 user := &auth.UserState{ 240 Username: "username", 241 Email: "email@test.com", 242 } 243 244 for _, test := range readyToBuyTests { 245 s.err = test.input 246 247 req, err := http.NewRequest("GET", "/v2/buy/ready", nil) 248 c.Assert(err, check.IsNil) 249 250 rsp := s.jsonReq(c, req, user) 251 c.Check(rsp.Status, check.Equals, test.status) 252 c.Check(rsp.Type, check.Equals, test.respType) 253 c.Assert(rsp.Result, check.FitsTypeOf, test.response) 254 c.Check(rsp.Result, check.DeepEquals, test.response) 255 } 256 }