1from typing import List 2from typing import Union 3 4import pytest 5 6 7class TestPasteCapture: 8 @pytest.fixture 9 def pastebinlist(self, monkeypatch, request) -> List[Union[str, bytes]]: 10 pastebinlist = [] # type: List[Union[str, bytes]] 11 plugin = request.config.pluginmanager.getplugin("pastebin") 12 monkeypatch.setattr(plugin, "create_new_paste", pastebinlist.append) 13 return pastebinlist 14 15 def test_failed(self, testdir, pastebinlist): 16 testpath = testdir.makepyfile( 17 """ 18 import pytest 19 def test_pass(): 20 pass 21 def test_fail(): 22 assert 0 23 def test_skip(): 24 pytest.skip("") 25 """ 26 ) 27 reprec = testdir.inline_run(testpath, "--pastebin=failed") 28 assert len(pastebinlist) == 1 29 s = pastebinlist[0] 30 assert s.find("def test_fail") != -1 31 assert reprec.countoutcomes() == [1, 1, 1] 32 33 def test_all(self, testdir, pastebinlist): 34 from _pytest.pytester import LineMatcher 35 36 testpath = testdir.makepyfile( 37 """ 38 import pytest 39 def test_pass(): 40 pass 41 def test_fail(): 42 assert 0 43 def test_skip(): 44 pytest.skip("") 45 """ 46 ) 47 reprec = testdir.inline_run(testpath, "--pastebin=all", "-v") 48 assert reprec.countoutcomes() == [1, 1, 1] 49 assert len(pastebinlist) == 1 50 contents = pastebinlist[0].decode("utf-8") 51 matcher = LineMatcher(contents.splitlines()) 52 matcher.fnmatch_lines( 53 [ 54 "*test_pass PASSED*", 55 "*test_fail FAILED*", 56 "*test_skip SKIPPED*", 57 "*== 1 failed, 1 passed, 1 skipped in *", 58 ] 59 ) 60 61 def test_non_ascii_paste_text(self, testdir, pastebinlist): 62 """Make sure that text which contains non-ascii characters is pasted 63 correctly. See #1219. 64 """ 65 testdir.makepyfile( 66 test_unicode="""\ 67 def test(): 68 assert '☺' == 1 69 """ 70 ) 71 result = testdir.runpytest("--pastebin=all") 72 expected_msg = "*assert '☺' == 1*" 73 result.stdout.fnmatch_lines( 74 [ 75 expected_msg, 76 "*== 1 failed in *", 77 "*Sending information to Paste Service*", 78 ] 79 ) 80 assert len(pastebinlist) == 1 81 82 83class TestPaste: 84 @pytest.fixture 85 def pastebin(self, request): 86 return request.config.pluginmanager.getplugin("pastebin") 87 88 @pytest.fixture 89 def mocked_urlopen_fail(self, monkeypatch): 90 """Monkeypatch the actual urlopen call to emulate a HTTP Error 400.""" 91 calls = [] 92 93 import urllib.error 94 import urllib.request 95 96 def mocked(url, data): 97 calls.append((url, data)) 98 raise urllib.error.HTTPError(url, 400, "Bad request", None, None) 99 100 monkeypatch.setattr(urllib.request, "urlopen", mocked) 101 return calls 102 103 @pytest.fixture 104 def mocked_urlopen_invalid(self, monkeypatch): 105 """Monkeypatch the actual urlopen calls done by the internal plugin 106 function that connects to bpaste service, but return a url in an 107 unexpected format.""" 108 calls = [] 109 110 def mocked(url, data): 111 calls.append((url, data)) 112 113 class DummyFile: 114 def read(self): 115 # part of html of a normal response 116 return b'View <a href="/invalid/3c0c6750bd">raw</a>.' 117 118 return DummyFile() 119 120 import urllib.request 121 122 monkeypatch.setattr(urllib.request, "urlopen", mocked) 123 return calls 124 125 @pytest.fixture 126 def mocked_urlopen(self, monkeypatch): 127 """Monkeypatch the actual urlopen calls done by the internal plugin 128 function that connects to bpaste service.""" 129 calls = [] 130 131 def mocked(url, data): 132 calls.append((url, data)) 133 134 class DummyFile: 135 def read(self): 136 # part of html of a normal response 137 return b'View <a href="/raw/3c0c6750bd">raw</a>.' 138 139 return DummyFile() 140 141 import urllib.request 142 143 monkeypatch.setattr(urllib.request, "urlopen", mocked) 144 return calls 145 146 def test_pastebin_invalid_url(self, pastebin, mocked_urlopen_invalid): 147 result = pastebin.create_new_paste(b"full-paste-contents") 148 assert ( 149 result 150 == "bad response: invalid format ('View <a href=\"/invalid/3c0c6750bd\">raw</a>.')" 151 ) 152 assert len(mocked_urlopen_invalid) == 1 153 154 def test_pastebin_http_error(self, pastebin, mocked_urlopen_fail): 155 result = pastebin.create_new_paste(b"full-paste-contents") 156 assert result == "bad response: HTTP Error 400: Bad request" 157 assert len(mocked_urlopen_fail) == 1 158 159 def test_create_new_paste(self, pastebin, mocked_urlopen): 160 result = pastebin.create_new_paste(b"full-paste-contents") 161 assert result == "https://bpaste.net/show/3c0c6750bd" 162 assert len(mocked_urlopen) == 1 163 url, data = mocked_urlopen[0] 164 assert type(data) is bytes 165 lexer = "text" 166 assert url == "https://bpaste.net" 167 assert "lexer=%s" % lexer in data.decode() 168 assert "code=full-paste-contents" in data.decode() 169 assert "expiry=1week" in data.decode() 170 171 def test_create_new_paste_failure(self, pastebin, monkeypatch): 172 import io 173 import urllib.request 174 175 def response(url, data): 176 stream = io.BytesIO(b"something bad occurred") 177 return stream 178 179 monkeypatch.setattr(urllib.request, "urlopen", response) 180 result = pastebin.create_new_paste(b"full-paste-contents") 181 assert result == "bad response: invalid format ('something bad occurred')" 182