# -*- coding: utf-8 -*- # Copyright 2012 Vincent Jacques # vincent@vincent-jacques.net # This file is part of PyGithub. http://vincent-jacques.net/PyGithub # PyGithub is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License # as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. # PyGithub is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. # You should have received a copy of the GNU Lesser General Public License along with PyGithub. If not, see . import os import sys import unittest import httplib import traceback import github class FakeHttpResponse: def __init__(self, status, headers, output): self.status = status self.__headers = headers self.__output = output def getheaders(self): return self.__headers def read(self): return self.__output def fixAuthorizationHeader(headers): if "Authorization" in headers: if headers["Authorization"].startswith("token "): headers["Authorization"] = "token private_token_removed" elif headers["Authorization"].startswith("Basic "): headers["Authorization"] = "Basic login_and_password_removed" else: # pragma no cover assert False class RecordingConnection: # pragma no cover def __init__(self, file, protocol, host, port, *args, **kwds): self.__file = file self.__protocol = protocol self.__host = host self.__port = str(port) self.__cnx = self._realConnection(host, port, *args, **kwds) def request(self, verb, url, input, headers): print verb, url, input, headers, self.__cnx.request(verb, url, input, headers) fixAuthorizationHeader(headers) self.__file.write(self.__protocol + " " + verb + " " + self.__host + " " + self.__port + " " + url + " " + str(headers) + " " + input.replace('\n', '').replace('\r', '') + "\n") def getresponse(self): res = self.__cnx.getresponse() status = res.status print "=>", status headers = res.getheaders() output = res.read() self.__file.write(str(status) + "\n") self.__file.write(str(headers) + "\n") self.__file.write(str(output) + "\n") return FakeHttpResponse(status, headers, output) def close(self): self.__file.write("\n") return self.__cnx.close() class RecordingHttpConnection(RecordingConnection): # pragma no cover _realConnection = httplib.HTTPConnection def __init__(self, file, *args, **kwds): RecordingConnection.__init__(self, file, "http", *args, **kwds) class RecordingHttpsConnection(RecordingConnection): # pragma no cover _realConnection = httplib.HTTPSConnection def __init__(self, file, *args, **kwds): RecordingConnection.__init__(self, file, "https", *args, **kwds) class ReplayingConnection: def __init__(self, testCase, file, protocol, host, port, *args, **kwds): self.__testCase = testCase self.__file = file self.__protocol = protocol self.__host = host self.__port = str(port) def request(self, verb, url, input, headers): fixAuthorizationHeader(headers) expectation = self.__file.readline().strip() self.__testCase.assertEqual(self.__protocol + " " + verb + " " + self.__host + " " + self.__port + " " + url + " " + str(headers) + " " + input.replace('\n', '').replace('\r', ''), expectation) def getresponse(self): status = int(self.__file.readline().strip()) headers = eval(self.__file.readline().strip()) output = self.__file.readline().strip() return FakeHttpResponse(status, headers, output) def close(self): self.__file.readline() def ReplayingHttpConnection(testCase, file, *args, **kwds): return ReplayingConnection(testCase, file, "http", *args, **kwds) def ReplayingHttpsConnection(testCase, file, *args, **kwds): return ReplayingConnection(testCase, file, "https", *args, **kwds) class BasicTestCase(unittest.TestCase): recordMode = False def setUp(self): unittest.TestCase.setUp(self) self.__fileName = "" self.__file = None if self.recordMode: # pragma no cover github.Requester.Requester.injectConnectionClasses( lambda ignored, *args, **kwds: RecordingHttpConnection(self.__openFile("wb"), *args, **kwds), lambda ignored, *args, **kwds: RecordingHttpsConnection(self.__openFile("wb"), *args, **kwds) ) import GithubCredentials self.login = GithubCredentials.login self.password = GithubCredentials.password self.oauth_token = GithubCredentials.oauth_token # @todo Remove client_id and client_secret from ReplayData (as we already remove login, password and oauth_token) # self.client_id = GithubCredentials.client_id # self.client_secret = GithubCredentials.client_secret else: github.Requester.Requester.injectConnectionClasses( lambda ignored, *args, **kwds: ReplayingHttpConnection(self, self.__openFile("r"), *args, **kwds), lambda ignored, *args, **kwds: ReplayingHttpsConnection(self, self.__openFile("r"), *args, **kwds) ) self.login = "login" self.password = "password" self.oauth_token = "oauth_token" self.client_id = "client_id" self.client_secret = "client_secret" def tearDown(self): unittest.TestCase.tearDown(self) self.__closeReplayFileIfNeeded() def __openFile(self, mode): for (_, _, functionName, _) in traceback.extract_stack(): if functionName.startswith("test") or functionName == "setUp" or functionName == "tearDown": if functionName != "test": # because in class Hook(Framework.TestCase), method testTest calls Hook.test fileName = os.path.join(os.path.dirname(__file__), "ReplayData", self.__class__.__name__ + "." + functionName + ".txt") if fileName != self.__fileName: self.__closeReplayFileIfNeeded() self.__fileName = fileName self.__file = open(self.__fileName, mode) return self.__file def __closeReplayFileIfNeeded(self): if self.__file is not None: if not self.recordMode: # pragma no branch self.assertEqual(self.__file.readline(), "") self.__file.close() def assertListKeyEqual(self, elements, key, expectedKeys): realKeys = [key(element) for element in elements] self.assertEqual(realKeys, expectedKeys) def assertListKeyBegin(self, elements, key, expectedKeys): realKeys = [key(element) for element in elements[: len(expectedKeys)]] self.assertEqual(realKeys, expectedKeys) class TestCase(BasicTestCase): def setUp(self): BasicTestCase.setUp(self) self.g = github.Github(self.login, self.password) def activateRecordMode(): # pragma no cover BasicTestCase.recordMode = True