def test_init_without_expected_arguments_causes_exception(self): '''Raises exception if client is requested without expected arguments. Either: a) url and token. b) url, user and pswd. ''' API_USR = '******' API_PWD = 'a_pswd' # Without arguments at all: self.assertRaises(Missing_Init_Arguments, TaigaClient) # Only (valid) URL (missing either token or both, user and pswd): with self.assertRaises( Missing_Init_Arguments, msg= 'A TiagaClient init missing token or user or pswd should have raised an Exception.' ): tmc = TaigaClient(url=self.API_URL) # Missing URL with user and pswd: with self.assertRaises( Missing_Init_Arguments, msg= 'A TaigaClient init missing the url should have raised an Exception.' ): tmc = TaigaClient(user=API_USR, pswd=API_PWD) # Missing URL with a (random) token: with self.assertRaises( Missing_Init_Arguments, msg= 'A TaigaClient init missing the url should have raised an Exception.' ): tmc = TaigaClient(token='some_clumsy_token') # Missing user: with self.assertRaises( Missing_Init_Arguments, msg= 'A TaigaClient init missing the user should have raised an Exception' ): tmc = TaigaClient(url=self.API_URL, pswd=API_PWD) # Missing pswd: with self.assertRaises( Missing_Init_Arguments, msg= 'A TaigaClient init missing the pswd should have raised an Exception.' ): tmc = TaigaClient(url=self.API_URL, user=API_USR)
def test_initialization(self): '''Taiga Client initializations.''' HTTP_OK = self.http_code_nr('OK') SAFE_API_COMMAND = 'projects' mock.register_uri(mock.GET, self.API_URL + SAFE_API_COMMAND, body=read_file('data/taiga/projects.body.RS'), status=HTTP_OK) mock.register_uri(mock.POST, self.API_URL + 'auth', body='{ "auth_token":"a_token" }', status=HTTP_OK) TST_ITEMS_PER_PAGE = 30 # user&pswd init(implicit url, user, pswd) executes (no exception): tmc = TaigaClient(self.API_URL, user='******', pswd='a_password') # a fresh user&pswd init sets no token: self.assertEqual(None, tmc.get_token()) # ... thus, it raises exception if executed before login(): with self.assertRaises(Exception): tmc.rq(SAFE_API_COMMAND) # ... but after login it executes a request (no exception): tmc.login() rs1 = tmc.basic_rq(SAFE_API_COMMAND) self.assertEqual(HTTP_OK, rs1.status_code) # API returns max 30 items per page: (get limit from response header?) lst = rs1.json() self.assertEqual(TST_ITEMS_PER_PAGE, len(lst)) # ... now it has a (non-None) token: fresh_token = tmc.get_token() self.assertFalse(None == fresh_token) # ... a brand new one: self.assertNotEqual(self.API_TKN, fresh_token) # a token re-init (url, explicit token) executes (no exception): tmc = TaigaClient(url=self.API_URL, token=self.API_TKN) # its token has changed as requested in the init command: self.assertEqual(self.API_TKN, tmc.get_token()) # and executes (the same valid) request (no exception): rs2 = tmc.basic_rq(SAFE_API_COMMAND) self.assertEqual(HTTP_OK, rs2.status_code)
def test_api_command(self): tmc = TaigaClient(url=self.API_URL, token=self.API_TKN) response1 = tmc.basic_rq( 'projects?is_backlog_activated=true&is_kanban_activated=true') if 200 != response1.status_code: print(response1.headers) print(response1) self.fail( "Coudn't test projects/id/stats because the request for project list failed." ) return lst = response1.json() print(str(len(lst)) + ' projects found.') print(response1.headers) print(lst) return for pj in lst: command_under_test = 'wiki?project={}'.format(pj['id']) response = tmc.rq(command_under_test) if 200 == response.status_code: rec = response.json() num = len(rec) if 0 < num: print( str(pj['id']) + ' has ' + str(len(rec)) + ' wiki pages.') # print(str(rec)) return
def setUpClass(cls): '''Set up Taiga service''' cls.API_URL = 'https://a.taiga.instance/API/V9/' cls.API_TKN = 'a_clumsy_token' # Default Taiga Client for testing: cls.TST_DTC = TaigaClient(url=cls.API_URL, token=cls.API_TKN)
def test_login_fail(self): '''Taiga denies permission.''' mock.register_uri(mock.POST, self.API_URL + 'auth', status=self.http_code_nr('UNAUTHORIZED'), body='''{ "etc":"etc" }''') tmc = TaigaClient(self.API_URL, user='******', pswd='a_pswd') with self.assertRaises(Exception): bah = tmc.login()
def test_proj_export(self): '''Taiga export doesn't work due to permissions.''' tmc = TaigaClient(url=self.API_URL, token=self.API_TKN) response = tmc.basic_rq('exporter/156665') if 403 != response.status_code: print(response.json) self.assertEqual(403, response.status_code) self.assertEqual('You do not have permission to perform this action.', response.json()['_error_message'])
def test_initialization(self): '''Test Taiga Client initializations.''' SAFE_API_COMMAND = 'projects' # user&pswd init(implicit url, user, pswd) executes (no exception): tmc = TaigaClient(self.API_URL, user=self.API_USR, pswd=self.API_PWD) # a fresh user&pswd init sets no token: self.assertEqual(None, tmc.get_token()) # ... thus, it raises exception if executed before login(): with self.assertRaises(Uninitiated_TaigaClient): tmc.basic_rq(SAFE_API_COMMAND) # ... but after login it executes a request (no exception): tmc.login() rs1 = tmc.basic_rq(SAFE_API_COMMAND) self.assertEqual(200, rs1.status_code) # API returns max 30 items per page: (get limit from response header?) lst = rs1.json() self.assertEqual(30, len(lst)) # ... now it has a (non-None) token: fresh_token = tmc.get_token() self.assertFalse(None == fresh_token) # ... a brand new one: self.assertNotEqual(self.API_TKN, fresh_token) # a token re-init (url, explicit token) executes (no exception): tmc = TaigaClient(url=self.API_URL, token=self.API_TKN) # its token has changed as requested in the init command: self.assertEqual(self.API_TKN, tmc.get_token()) # and executes (the same valid) request (no exception): rs2 = tmc.basic_rq(SAFE_API_COMMAND) self.assertEqual(200, rs2.status_code)
def test_init_with_user_and_pswd(self): '''A pswd-born client is created without token. Design: - Data used in client init doesn't affect this requirement. This testcase inits it with valid data (checked in other testcases). A similar testcase tests this with invalid data. - This test doesn't actually call to a real server, but it is in this class because it uses valid data. Thar data is proven valid through real calls in other tests of this class. ''' tmc = TaigaClient(url=self.API_URL, user=self.API_USR, pswd=self.API_PWD) self.assertEqual(None, tmc.get_token())
def test_under_construction(self): '''This test is under construction.''' tmc = TaigaClient(url=self.API_URL, token=self.API_TKN) response = tmc.basic_rq('new API command here') print('/--- Rq:') print(response.request.headers) print(response.request.body) print(response.headers) print(response.status_code) print(response.text[:100] + ' ...') print(response.json) print('\\--- Rq')
def test_wrong_token(self): '''Taiga rejects wrong tokens. Taiga's response to a wrong token causes exception in rq() but not in basic_rq(). ''' SAFE_API_COMMAND = 'projects' EXPECTED_RS_JSON = { "_error_message": "Invalid token", "_error_type": "taiga.base.exceptions.NotAuthenticated" } tmc = TaigaClient(url=self.API_URL, token='wrong_token') response = tmc.basic_rq(SAFE_API_COMMAND) self.assertEqual(401, response.status_code) self.assertDictEqual(EXPECTED_RS_JSON, response.json()) with self.assertRaises(Exception): response = tmc.rq(SAFE_API_COMMAND)
def capture_basic_RS(self, url, destination): '''Testing maintainance utility to capture http responses. Captures response headers and body in respective files. :param: destination: 'PART'-marked path to the file where to save. Will create 2 files: HEAD and BODY. ''' config = Utilities.read_test_config(CFG_FILE) taiga = TaigaClient(url=config['url'], token=config['tkn']) response = taiga.basic_rq(url) if 200 == response.status_code: with open(destination.replace('PART', 'head'), 'w') as fh: fh.write(str(response.headers)) with open(destination.replace('PART', 'body'), 'w') as fb: fb.write(response.text) else: print('FAIL:') print(response.headers) print(response.text)
def setUpClass(cls): '''Set up tests.''' # clean up common test data: cls.API_URL = None cls.API_USR = None cls.API_PWD = None cls.API_TKN = None cls.TST_CFG = None cls.TST_DTC = None # read config file: cfg = Utilities.read_test_config(CFG_FILE) # take url: if cfg['url']: cls.API_URL = cfg['url'] else: raise Exception('Missing url in {}.'.format(CFG_FILE)) # take credentials (2 options): has_usr_pwd = cfg['usr'] and cfg['pwd'] if has_usr_pwd: cls.API_USR = cfg['usr'] cls.API_PWD = cfg['pwd'] # print( 'Debug: TestTaigaClient.setup_taiga has read user {}, pswd {}.'.format( cls.API_USR , cls.API_PWD ) ) has_token = cfg['tkn'] if has_token: cls.API_TKN = cfg['tkn'] # print( 'Debug: TestTaigaClient.setup_taiga has read token {}.'.format( cls.API_TKN ) ) if not (has_usr_pwd or hastoken): raise Exception( 'TestTaigaClient.setup_taiga FAILED due to test data missing: credentials missing in test config file.' ) # load other test data: cls.TST_CFG = cfg['cfg'] if has_token: cls.TST_DTC = TaigaClient(url=cls.API_URL, token=cls.API_TKN)
def test_init_with_user_and_pswd(self): '''A client is created without token. Client init doesn't immediately connect to API. This would fail later on, at login. ''' mock.register_uri(mock.POST, self.API_URL + 'auth', body=read_file('data/taiga/login.body.RS').replace( "'", '"'), status=self.http_code_nr('OK')) # a fresh user&pswd client lacks a token yet: tc = TaigaClient(url=self.API_URL, user='******', pswd='an_invalid_password') self.assertEqual(None, tc.get_token()) # without token nothing works (own exception): DUMMY_URL = 'should NOT even try' with self.assertRaises(Uninitiated_TaigaClient): bah = tc.basic_rq(DUMMY_URL) with self.assertRaises(Uninitiated_TaigaClient): bah = tc.rq(DUMMY_URL) with self.assertRaises(Uninitiated_TaigaClient): bah = tc.proj_stats(DUMMY_URL) with self.assertRaises(Uninitiated_TaigaClient): bah = tc.proj_issues_stats(DUMMY_URL) with self.assertRaises(Uninitiated_TaigaClient): bah = tc.proj(DUMMY_URL) with self.assertRaises(Uninitiated_TaigaClient): TST_VALID_LIST = 'stats' bah = tc.get_lst_data_from_api(TST_VALID_LIST, 'a_project') # right after login, token is set: tc.login() self.assertEqual('a_Mocked_Token', tc.get_token()) # now, the dummy, unmocked url causes a different exception: with self.assertRaises(requests.exceptions.ConnectionError): bah = tc.rq('DummyEndPoint')