def check_easy_not_moving_like_medium(self): if self.is_easy_not_moving_like_medium: return CheckResult.correct() program = TestedProgram() program.start() program.execute("start user easy") output = program.execute("2 2") game_grid = Grid.from_output(output, 2) cells = game_grid.get_grid() if cells[0][0] == CellState.EMPTY and cells[2][2] == CellState.EMPTY: output = program.execute("1 1") game_grid = Grid.from_output(output, 2) if game_grid.get_grid()[2][2] == CellState.EMPTY: self.is_easy_not_moving_like_medium = True else: output = program.execute("1 3") game_grid = Grid.from_output(output, 2) if game_grid.get_grid()[2][0] == CellState.EMPTY: self.is_easy_not_moving_like_medium = True program.stop() return CheckResult.correct()
def test3(self): pr = TestedProgram() pr.start() output = pr.execute('header').strip().lower() if len(output.split('\n')) != 1 or 'formatter' not in output.strip().lower(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') output = pr.execute('ordered-list').strip().lower() if len(output.split('\n')) != 1 or 'formatter' not in output.strip().lower(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') output = pr.execute('unordered-list').strip().lower() if len(output.split('\n')) != 1 or 'formatter' not in output.strip().lower(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') output = pr.execute('link').strip().lower() if len(output.split('\n')) != 1 or 'formatter' not in output.strip().lower(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') output = pr.execute('inline-code').strip().lower() if len(output.split('\n')) != 1 or 'formatter' not in output.strip().lower(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') output = pr.execute('new-line').strip().lower() if len(output.split('\n')) != 1 and 'formatter' not in output.strip().lower(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') pr.execute('!done') if not pr.is_finished(): return CheckResult.wrong('Your program should finish its execution whenever !done is an input') return CheckResult.correct()
def test(self): program = TestedProgram() program.start() output = program.execute('test') if output != 'test\n': return CheckResult.wrong('') output = program.execute('test\n') if output != 'test\n': return CheckResult.wrong('') output = program.execute('test\n\n') if output != 'test\nempty\n': return CheckResult.wrong('') output = program.execute('test\n\n\n') if output != 'test\nempty\nempty\n': return CheckResult.wrong('') output = program.execute('\ntest\n\n\n') if output != 'empty\ntest\nempty\nempty\n': return CheckResult.wrong('') output = program.execute('test\n\ntest\n\ntest\n\n\n') if output != 'test\nempty\ntest\nempty\ntest\nempty\nempty\n': return CheckResult.wrong('') return CheckResult.correct()
def check_create_resume_from_profile(self) -> CheckResult: opener = urllib.request.build_opener( urllib.request.HTTPCookieProcessor(self.cookie_jar)) try: response = opener.open(self.get_url() + 'home') except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the home page.') csrf_options = re.findall(b'<input[^>]+value="(?P<csrf>\\w+)"[^>]*>', response.read()) if not csrf_options: return CheckResult.wrong('Missing csrf_token in the form') try: response = opener.open(f'{self.get_url()}resume/new', data=urllib.parse.urlencode({ 'description': self.OCCUPATION, 'csrfmiddlewaretoken': csrf_options[0], }).encode()) except urllib.error.URLError as err: return CheckResult.wrong(f'Cannot create resume: {err.reason}') try: page = self.read_page(f'{self.get_url()}resumes') description = f'{self.USERNAME}: {self.OCCUPATION}' if description not in page: return CheckResult.wrong( f'Resumes page does not contain newly created resume') return CheckResult.correct() except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the resumes page.')
async def test_main_page_structure_async(self): browser = await self.launch_and_get_browser() page = await browser.newPage() await page.goto(self.get_url()) cards_div = await page.querySelector('div.cards') if cards_div is None: raise WrongAnswer("Can't find <div> block with class 'cards'") button = await self.get_submit_button(page) if button is None: raise WrongAnswer( "Can't find a button with 'submit-button' class!") input_field = await self.get_input_field(page) if input_field is None: raise WrongAnswer("Can't find input field with 'input-city' id!") await self.check_cards_in_the_page(page, 0) await self.close_browser(browser) return CheckResult.correct()
def check_create_resumes(self) -> CheckResult: connection = sqlite3.connect(self.attach.test_database) cursor = connection.cursor() try: cursor.executemany( 'INSERT INTO auth_user ' '(`id`, `username`, `email`, `is_staff`, `password`, `is_superuser`, ' '`first_name`, `last_name`, `is_active`, `date_joined`) ' 'VALUES (?, ?, ?, ?, "", 0, "", "", 1, datetime())', INITIAL_USERS[len(INITIAL_VACANCIES):]) cursor.executemany( 'INSERT INTO resume_resume (`author_id`, `description`) VALUES (?, ?)', INITIAL_RESUMES) connection.commit() cursor.execute( 'SELECT `author_id`, `description` FROM resume_resume') result = cursor.fetchall() for item in INITIAL_RESUMES: if item not in result: return CheckResult.wrong('Check your Resume model') return CheckResult.correct() except sqlite3.DatabaseError as err: return CheckResult.wrong(str(err))
def stage4_monochromatic_test_invalid_data(self): url = self.get_url('color-harmony/') colors = [[-50, 0, 100], [150, 50, 999], [150, 100, -10]] for i in range(len(colors)): data = { "representation": "hsv", "color": colors[i], "harmony": "monochromatic" } response = requests.post(url, json=data) if response.status_code != 400: if response.status_code == 500: return CheckResult.wrong(self.msg_500 + ". (monochromatic)" + ". path_info: /color-harmony/") if response.status_code == 200: return CheckResult.wrong(self.msg_400_expected + ". (monochromatic)" + ". path_info: /color-harmony/") msg = f"""received HTTP status code: {response.status_code}, in response to invalid data: {data}.(monochromatic). path_info: /color-harmony/""" return CheckResult.wrong(msg) if response.status_code == 400: if response.json() != {"error": "Invalid data."}: return CheckResult.wrong(self.msg_400_expected + ". (monochromatic)" + ". path_info: /color-harmony/") return CheckResult.correct()
def conversion_processor(self, colors, original, conversion, conversion_dict): url = self.get_url('convert-color/') for i in range(len(colors)): data = { "representation": original, "color": colors[i], "conversion": conversion } response = requests.post(url, json=data) if response.status_code == 500: return CheckResult.wrong( self.msg_500 + f""", while converting {original} to {conversion}. path_info: /convert-color/""" ) if response.status_code != 200: return CheckResult.wrong( f"""HTTP code: {response.status_code}... Couldn't connect to /convert-color/""" ) if response.json() != conversion_dict[i]: return CheckResult.wrong(self.msg_200_invalid + ". path_info: /convert-color/") return CheckResult.correct()
def check_medium_ai(self): program = TestedProgram() program.start() program.execute("start user medium") output = program.execute("2 2") game_grid = Grid.from_output(output, 2) cells = game_grid.get_grid() if cells[0][0] == CellState.EMPTY and cells[2][2] == CellState.EMPTY: output = program.execute("1 1") game_grid = Grid.from_output(output, 2) if game_grid.get_grid()[2][2] == CellState.EMPTY: return CheckResult.wrong( "Looks like your Medium level AI doesn't make a correct move!" ) else: output = program.execute("1 3") game_grid = Grid.from_output(output, 2) if game_grid.get_grid()[2][0] == CellState.EMPTY: return CheckResult.wrong( "Looks like your Medium level AI doesn't make a correct move!" ) program.stop() return CheckResult.correct()
def test_bad_parameters(self): program = TestedProgram() program.start() output = program.execute("start") if "bad parameters" not in output.lower(): return CheckResult.wrong( "After entering start command with wrong parameters you should print " "'Bad parameters!' and ask to enter a command again!") output = program.execute("start easy") if "bad parameters" not in output.lower(): return CheckResult.wrong( "After entering start command with wrong parameters you should print " "'Bad parameters!' and ask to enter a command again!") program.execute("exit") if not program.is_finished(): return CheckResult.wrong( "After entering 'exit' command you should stop the program!") return CheckResult.correct()
def test2(self): pr = TestedProgram() pr.start() formatters = ['plain', 'bold', 'italic', 'header', 'ordered-list', 'unordered-list', 'link', 'inline-code', 'line-break'] commands = ['!help', '!done'] output = list(map(lambda item: item.lower(), pr.execute('!help').split('\n'))) if len(output) != 3: return CheckResult.wrong('!help command should return the list of available formatting types, and the list of special commands, on separate rows, and the prompt a user for an input') for formatter in formatters: if formatter not in output[0].split(): return CheckResult.wrong('One or more formatting types are not present in the output of !help command') for command in commands: if command not in output[1].split(): return CheckResult.wrong('One or more special commands are not present in the output of !help command') if 'formatter' not in output[2].strip(): return CheckResult.wrong('A user should be prompted for input again, i.e "- Choose a formatter: > "') pr.execute('!done') if not pr.is_finished(): return CheckResult.wrong('Your program should finish its execution whenever !done is an input') return CheckResult.correct()
def check_coming_soon_page(self) -> CheckResult: self.__setup() try: page = self.read_page(self.coming_soon_page_link) except urllib.error.URLError: return CheckResult.wrong( f'Cannot connect to the "Coming soon" page ({self.coming_soon_page_link}).' ) opener = urllib.request.build_opener( urllib.request.HTTPCookieProcessor(self.cookie_jar)) try: response = opener.open(self.coming_soon_page_link) except urllib.error.URLError: return CheckResult.wrong( f'Cannot connect to the "Coming soon" page ({self.coming_soon_page_link}).' ) coming_soon_text = 'Coming soon' # response.url for the backward compatibility if (coming_soon_text not in page and response.url != self.main_page_link): return CheckResult.wrong( f'"Coming soon" page ({self.coming_soon_page_link}) should contain "Coming soon" text' ) return CheckResult.correct()
def check_main_page_create_link(self): self.__setup() create_link = '/news/create/' try: page = self.read_page(self.main_page_link) except urllib.error.URLError: return CheckResult.wrong( f'Cannot connect to the main page ({self.main_page_link}).') links_from_page = re.findall(self.COMMON_LINK_PATTERN, page, re.S) links_from_page = self.__stripped_list(links_from_page) if create_link not in links_from_page: return CheckResult.wrong( f'Main page ({self.main_page_link}) should contain <a> element with href {create_link}' ) if len(links_from_page) - 1 != len(self.news_data): return CheckResult.wrong( f'Main page ({self.main_page_link}) should contain {len(self.news_data) + 1} <a> elements. ' f'{len(self.news_data)} elements with href to news pages from the json file data ' f'and one element with href {create_link}. ' f'Now main page contains {len(links_from_page)} <a> elements.') return CheckResult.correct()
def check_signup(self) -> CheckResult: opener = urllib.request.build_opener( urllib.request.HTTPCookieProcessor(self.cookie_jar)) try: response = opener.open(f'{self.get_url()}signup') except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the signup page.') csrf_options = re.findall(b'<input[^>]+value="(?P<csrf>\\w+)"[^>]*>', response.read()) if not csrf_options: return CheckResult.wrong('Missing csrf_token in the form') try: response = opener.open(f'{self.get_url()}signup', data=urllib.parse.urlencode({ 'csrfmiddlewaretoken': csrf_options[0], 'username': self.USERNAME, 'password1': self.PASSWORD, 'password2': self.PASSWORD, }).encode()) if f'login' in response.url: return CheckResult.correct() return CheckResult.wrong('Cannot signup: problems with form') except urllib.error.URLError as err: return CheckResult.wrong(f'Cannot signup: {err.reason}')
def check_hard_ai(self): program = TestedProgram() program.start() output = program.execute("start user hard") grid = Grid.from_output(output) next_move = Minimax.get_move(grid, CellState.X) output = program.execute(f"{next_move.x + 1} {next_move.y + 1}") while "win" not in output.lower() and "draw" not in output.lower(): grid_after_user_move = Grid.from_output(output) grid_after_ai_move = Grid.from_output(output, 2) ai_move = Grid.get_move(grid_after_user_move, grid_after_ai_move) correct_minimax_positions = Minimax.get_available_positions( grid_after_user_move, CellState.O) if ai_move not in correct_minimax_positions: return CheckResult.wrong( "Your minimax algorithm is wrong! It chooses wrong positions to make a move!" ) next_move = Minimax.get_move(grid_after_ai_move, CellState.X) output = program.execute(f"{next_move.x + 1} {next_move.y + 1}") return CheckResult.correct()
def check_greeting(self) -> CheckResult: try: main_page = self.read_page(self.get_url()) if 'Welcome to HyperJob!' in main_page: return CheckResult.correct() return CheckResult.wrong( 'Main page should contain "Welcome to HyperJob!" line') except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the menu page.')
def check_result_in_file(self, attach): try: with open('output.md', 'r') as outfile: output = outfile.read() if output != self.answers[attach]: return CheckResult.wrong('The result written to the output file is wrong.') except IOError: return CheckResult.wrong('The output file is not found.') return CheckResult.correct()
def test(self, inp, correct_lines_number): program = TestedProgram() program.start() output = program.execute(inp) if f"Input line number {correct_lines_number}" not in output or \ f"Input line number {correct_lines_number + 1}" in output: return CheckResult.wrong('') return CheckResult.correct()
def check_medium_vs_medium(self): program = TestedProgram() program.start() output = program.execute("start medium medium") grids = Grid.all_grids_from_output(output) Grid.check_grid_sequence(grids) return CheckResult.correct()
def check_main_page_search(self): self.__setup() q = '2' news_data = copy.deepcopy(self.news_data) for news in news_data: created_date = datetime.strptime(news['created'], '%Y-%m-%d %H:%M:%S') \ .date() news['created_date_str'] = created_date.strftime('%Y-%m-%d') all_headers = set((x['created_date_str'] for x in news_data)) visible_headers = set( (x['created_date_str'] for x in news_data if q in x['title'])) invisible_headers = all_headers - visible_headers visible_titles = [x['title'] for x in news_data if q in x['title']] invisible_titles = [ x['title'] for x in news_data if q not in x['title'] ] try: search_page_link = self.main_page_link + f'?q={q}' page = self.read_page(search_page_link) except urllib.error.URLError: return CheckResult.wrong(f'Cannot connect to the search page.') h4_headers = re.findall(self.H4_PATTERN, page, re.S) h4_headers = self.__stripped_list(h4_headers) for header in visible_headers: if header not in h4_headers: return CheckResult.wrong( 'Search page should contain headers with found news') for header in invisible_headers: if header in h4_headers: return CheckResult.wrong( 'Search page should not contain headers with unfound news') titles = re.findall(self.TEXT_LINK_PATTERN, page, re.S) titles = self.__stripped_list(titles) for title in visible_titles: if title not in titles: return CheckResult.wrong( 'Search page should contain found news') for title in invisible_titles: if title in titles: return CheckResult.wrong( 'Search page should not contain unfound news') return CheckResult.correct()
def check_vacancies(self) -> CheckResult: try: page = self.read_page(f'{self.get_url()}vacancies') for person, vacancy in zip(INITIAL_USERS, INITIAL_VACANCIES): description = f'{person[1]}: {vacancy[1]}' if description not in page: return CheckResult.wrong( f'Vacancies page should contain vacancies in form <username>: <description>' ) return CheckResult.correct() except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the vacancies page.')
def check_hard_vs_hard(self): program = TestedProgram() program.start() output = program.execute("start hard hard") if "draw" not in output.lower(): return CheckResult.wrong( "The result of the game between minimax algorithms should be always 'Draw'!\n" "Make sure your output contains 'Draw'.") return CheckResult.correct()
def check_resumes(self) -> CheckResult: try: page = self.read_page(f'{self.get_url()}resumes') for person, resume in zip(INITIAL_USERS[len(INITIAL_VACANCIES):], INITIAL_RESUMES): description = f'{person[1]}: {resume[1]}' if description not in page: return CheckResult.wrong( f'Resumes page should contain resumes in form <username>: <description>' ) return CheckResult.correct() except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the resumes page.')
def check_forbid_to_create_vacancy(self) -> CheckResult: opener = urllib.request.build_opener( urllib.request.HTTPCookieProcessor(self.cookie_jar)) try: response = opener.open(f'{self.get_url()}home') except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the home page.') csrf_options = re.findall(b'<input[^>]+value="(?P<csrf>\\w+)"[^>]*>', response.read()) if not csrf_options: return CheckResult.correct() OTHER_OCCUPATION = 'Marketing Coordinator' try: response = opener.open(f'{self.get_url()}vacancy/new', data=urllib.parse.urlencode({ 'description': OTHER_OCCUPATION, 'csrfmiddlewaretoken': csrf_options[0], }).encode()) return CheckResult.wrong( 'Should not allow usual users create vacancies') except urllib.error.URLError as err: if 'Forbidden' not in err.reason: return CheckResult.wrong( f'Wrong response for forbidden requests: {err.reason}') try: page = self.read_page(f'{self.get_url()}vacancies') if OTHER_OCCUPATION in page: return CheckResult.wrong( f'Vacancies page should not contain vacancies from usual users' ) return CheckResult.correct() except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the vacancies page.')
def test1(self): pr = TestedProgram() pr.start() output = pr.execute('random').strip().lower() if 'unknown format' not in output.strip().lower() or 'command' not in output.strip().lower(): return CheckResult.wrong('In case of an unknown formatting type the program should return the corresponding message: "Unknown formatting type or command"') pr.execute('!done') if not pr.is_finished(): return CheckResult.wrong('Your program should finish its execution whenever !done is an input') return CheckResult.correct()
def check_medium_not_moving_like_hard(self): if self.is_medium_not_moving_like_hard: return CheckResult.correct() program = TestedProgram() program.start() program.execute("start user medium") output = program.execute("2 2") user_move_grid = Grid.from_output(output, 1) medium_move_grid = Grid.from_output(output, 2) medium_move = Grid.get_move(user_move_grid, medium_move_grid) minimax_correct_positions = Minimax.get_available_positions(user_move_grid, CellState.O) if medium_move not in minimax_correct_positions: self.is_medium_not_moving_like_hard = True return CheckResult.correct()
def check_random(self): average_score = 0 for i in range(len(self.easy_ai_moves)): average_score += (i + 1) * self.easy_ai_moves[i] average_score /= 8 expected_value = (1 + 2 + 3 + 4 + 6 + 7 + 8 + 9) * 100 / 8 / 8 if abs(average_score - expected_value) > 20: return CheckResult.wrong("Looks like your Easy level AI doesn't make a random move!") return CheckResult.correct()
def check_links(self) -> CheckResult: try: page = self.read_page(self.get_url()) links = re.findall(self.ELEMENT_PATTERN, page) for link in ( '/login', '/signup', '/vacancies', '/resumes', '/home', ): if link not in links: return CheckResult.wrong( f'Menu page should contain <a> element with href {link}' ) return CheckResult.correct() except urllib.error.URLError: return CheckResult.wrong('Cannot connect to the menu page.')
def check_coming_soon_page_redirect(self) -> CheckResult: self.__setup() opener = urllib.request.build_opener( urllib.request.HTTPCookieProcessor(self.cookie_jar)) try: response = opener.open(self.coming_soon_page_link) except urllib.error.URLError: return CheckResult.wrong( f'Cannot connect to the "Coming soon" page ({self.coming_soon_page_link}).' ) if response.url != self.main_page_link: return CheckResult.wrong( f'"Coming soon" ({self.coming_soon_page_link}) page should redirects to the {self.main_page_link}' ) return CheckResult.correct()
def check_easy_ai(self): program = TestedProgram() program.start() output = program.execute("2 2") grid_after_ai_move = Grid.from_output(output, 2) cells = grid_after_ai_move.get_grid() for i in range(9): if i == 4: continue if cells[int(i / 3)][i % 3] == CellState.O: self.easy_ai_moves[i] += 1 return CheckResult.correct()