def test_hide_note(self): params_list = [ { "page": 1, "pageSize": 10 }, { "page": 1 }, { "page": "foobar" }, { "page": "foobar", "pageSize": "foo" }, ] NotesService.upsert_note(VALID_ID, "hello", utils.now()) for params in params_list: with self.subTest(**params): rv = self.client.post("/notes/" + VALID_ID + "/hide", data=params) self.assertEqual(rv.status_code, 302) self.assertTrue(NotesService.get_note(VALID_ID).hidden)
def get_note(note_id): note = NotesService.get_note(note_id) NotesService.mark_as_read(note) is_link = is_note_link(note) template = "view-link.html" if is_link else "view.html" return render_template(template, contents=note.contents)
def test_upate_read_note(self): note = NotesService.upsert_note(VALID_ID, "Test", utils.now()) self.assertFalse(note.read) NotesService.mark_as_read(note) self.assertTrue(note.read) note = NotesService.upsert_note(VALID_ID, "foobar", utils.now(1000)) self.assertFalse(note.read)
def test_view_notes(self): for _ in range(50): NotesService.upsert_note(NotesService.generate_note_id(), "hello", utils.now()) urls = ["/notes", "/notes?page=1", "/notes?page=foobar"] for url in urls: with self.subTest(url=url): with self.client.get(url) as rv: self.assertEqual(rv.status_code, 200)
def hide_note(note_id): NotesService.hide_note(note_id) page = form_int("page", 1) page_size = form_int("pageSize") if page_size == 1: # We are hiding the last note on the page page -= 1 return redirect( url_for(".get_notes") + ("?page={}".format(page) if page > 1 else ""))
def get_notes(): page = args_int("page", 1) query = args_str("q") pagination = NotesService.paginate_notes(page, query=query) url_page_1 = url_for(".get_notes") url_previous = url_for(".get_notes") if pagination.prev_num and pagination.prev_num > 1: url_previous += "?page={}".format(pagination.prev_num) url_next = "{}?page={}".format(url_for(".get_notes"), pagination.next_num) if query: param = "q={}".format(query) url_page_1 += "?" + param url_previous += ("&" if "?" in url_previous else "?") + param url_next += "&" + param return render_template( "notes.html", pagination=pagination, url_page_1=url_page_1, url_previous=url_previous, url_next=url_next, query=query or "", t=t, )
def test_note_mark_as_read(self): note = NotesService.upsert_note(VALID_ID, "hello", utils.now()) self.assertFalse(note.read) with self.client.get("/notes/" + VALID_ID) as rv: self.assertEqual(rv.status_code, 200) self.assertTrue(note.read)
def test_create_empty_note(self): rv = self.client.put( "/notes/" + VALID_ID + "?timestamp=1", data="", headers={"Content-type": "text/plain"}, ) self.assertEqual(rv.status_code, 200) note = NotesService.get_note(VALID_ID) self.assertEqual(note.contents, "")
def test_pretty_preview(self): notes_previews = [ ("hello", "hello"), ("hello ", "hello"), ("hello \nfoobar", "hello"), (" hello", "hello"), ("helloooooooooooooooo", "hellooooooooooo"), ("\nhello", "hello"), ("\n\n\nhello", "hello"), ("hello\nfoobar", "hello"), ("hello\nfooooooooooooooooo", "hello"), ("fooooooooooooooooo\nhello", "foooooooooooooo"), ("", ""), ] for note, preview in notes_previews: with self.subTest(note=note, preview=preview): note = NotesService.upsert_note( NotesService.generate_note_id(), note, utils.now() ) self.assertEqual(preview, note.preview(15))
def test_id_is_not_valid(self): ids = [ "69ffae8c08a4fbebadece21021c380800", None, "hello", "123", "69ffae8c08a4fbebadece21021c3808", ] for i in ids: with self.subTest(i=i): self.assertFalse(NotesService.id_is_valid(i))
def test_pagination_hidden(self): NotesService.upsert_note(VALID_ID, "Test", utils.now()) pagination = NotesService.paginate_notes(page=1) self.assertEqual(len(pagination.items), 1) NotesService.hide_note(VALID_ID) pagination = NotesService.paginate_notes(page=1) self.assertEqual(len(pagination.items), 0)
def test_previews_pagination(self): total_notes = random.randint(20, 50) page_size = 15 for _ in range(total_notes): NotesService.upsert_note( NotesService.generate_note_id(), "Test", utils.now() ) ids = set() for i in range(1, 1 + total_notes // page_size): pagination = NotesService.paginate_notes(page=i, page_size=page_size) self.assertLessEqual(len(pagination.items), page_size) self.assertGreater(len(pagination.items), 0) page_ids_set = {note.id for note in pagination.items} self.assertEqual(len(page_ids_set), len(pagination.items)) previous_len = len(ids) ids |= page_ids_set self.assertEqual(len(ids), previous_len + len(page_ids_set))
def upsert_note(note_id): if not NotesService.id_is_valid(note_id): abort(400) if (request.content_length or 0) > current_app.config["MAX_NOTE_LENGTH"]: abort(413) timestamp_millis = args_int("timestamp") seconds = timestamp_millis // 1000 millis = timestamp_millis % 1000 timestamp = datetime.utcfromtimestamp(seconds) + timedelta( milliseconds=millis) contents = request.get_data(as_text=True) try: NotesService.upsert_note(note_id, contents, timestamp) except ModelException: current_app.logger.exception("Error storing note:") abort(500) current_app.logger.info("Note ID {} created/updated.".format(note_id)) return {"id": note_id, "timestamp": timestamp_millis}
def test_update_note(self): with self.assertRaises(NoteNotFound): note = NotesService.get_note(VALID_ID) NotesService.upsert_note(VALID_ID, "Hello, world!", utils.now()) NotesService.upsert_note(VALID_ID, "goodbye", utils.now()) note = NotesService.get_note(VALID_ID) self.assertEqual(note.contents, "goodbye")
def test_hide_note(self): NotesService.upsert_note(VALID_ID, "Hello, world!", utils.now()) note = NotesService.get_note(VALID_ID) self.assertFalse(note.hidden) NotesService.hide_note(VALID_ID) note = NotesService.get_note(VALID_ID) self.assertTrue(note.hidden)
def test_note_is_link(self): notes = [ ("http://example.com", True), ("https://place.com", True), ("https://place.com/foobar", True), ("https://place.com/foobar#foo", True), ("https://place.com/foobar?q=hello", True), ("hello there", False), ("something\nsomething", False), ("http://hello.com\nmore stuff", False), ("", False), ] for note, is_link in notes: with self.subTest(note=note): note = NotesService.upsert_note(VALID_ID, note, utils.now()) self.assertEqual(is_note_link(note), is_link)
def test_view_notes_query(self): NotesService.upsert_note(NotesService.generate_note_id(), "aaaaaa", utils.now()) NotesService.upsert_note(NotesService.generate_note_id(), "bbbbbb", utils.now()) with self.client.get("/notes?q=aaa") as rv: self.assertEqual(rv.status_code, 200) data = rv.data.decode("utf-8") self.assertTrue("aaaaaa" in data) self.assertTrue("bbbbbb" not in data)
def test_update_note(self): rv = self.client.put( "/notes/" + VALID_ID + "?timestamp=1000", data="foo", headers={"Content-type": "text/plain"}, ) self.assertEqual(rv.status_code, 200) rv = self.client.put( "/notes/" + VALID_ID + "?timestamp=2000", data="bar", headers={"Content-type": "text/plain"}, ) self.assertEqual(rv.status_code, 200) note = NotesService.get_note(VALID_ID) self.assertEqual(note.contents, "bar") self.assertEqual(utils.timestamp_seconds(note.modified), 2)
def test_try_update_note_invalid_timestamp(self): rv = self.client.put( "/notes/" + VALID_ID + "?timestamp=2000", data="foo", headers={"Content-type": "text/plain"}, ) self.assertEqual(rv.status_code, 200) # Try sending again with invalid timestamp rv = self.client.put( "/notes/" + VALID_ID + "?timestamp=foobar", data="bar", headers={"Content-type": "text/plain"}, ) self.assertEqual(rv.status_code, 200) note = NotesService.get_note(VALID_ID) self.assertEqual(note.contents, "foo") self.assertEqual(utils.timestamp_seconds(note.modified), 2)
def index(): return render_template("index.html", note_id=NotesService.generate_note_id(), t=t)
def test_notes_search(self): note_1_id = NotesService.generate_note_id() note_2_id = NotesService.generate_note_id() note_3_id = NotesService.generate_note_id() NotesService.upsert_note(note_1_id, "hello world", utils.now()) NotesService.upsert_note(note_2_id, "hello there", utils.now(1)) NotesService.upsert_note(note_3_id, "aaaaaaaaaa", utils.now(2)) notes = NotesService.paginate_notes(1, query="hello world") self.assertEqual(notes.total, 1) self.assertEqual(notes.items[0].contents, "hello world") notes = NotesService.paginate_notes(1, query="hello") self.assertEqual(notes.total, 2) self.assertEqual(notes.items[1].contents, "hello world") self.assertEqual(notes.items[0].contents, "hello there") notes = NotesService.paginate_notes(1, query="aa") self.assertEqual(notes.total, 1) self.assertEqual(notes.items[0].contents, "aaaaaaaaaa") notes = NotesService.paginate_notes(1, query="foobarfoobar") self.assertEqual(notes.total, 0)
def test_view_note(self): NotesService.upsert_note(VALID_ID, "hello", utils.now()) with self.client.get("/notes/" + VALID_ID) as rv: self.assertEqual(rv.status_code, 200)
def test_create_note(self): NotesService.upsert_note(VALID_ID, "Hello, world!", utils.now()) note = NotesService.get_note(VALID_ID) self.assertEqual(note.id, VALID_ID)
def test_id_is_valid(self): ids = ["a" * 32, VALID_ID, "1" * 32] for i in ids: with self.subTest(i=i): self.assertTrue(NotesService.id_is_valid(i))