def test_bulk_edit(): assert Foo.objects.all().count() == 0 Foo(a=1, b="").save() Foo(a=2, b="").save() Foo(a=3, b="").save() Foo(a=4, b="").save() class TestTable(Table): a = Column.number( sortable=False, bulk__show=True ) # turn off sorting to not get the link with random query params b = Column(bulk__show=True) result = render_table(request=RequestFactory(HTTP_REFERER='/').get( "/", dict(pk_1='', pk_2='', a='0', b='changed')), table=TestTable(data=Foo.objects.all())) assert '<form method="post" action=".">' in result assert '<input type="submit" class="button" value="Bulk change"/>' in result render_table(request=RequestFactory(HTTP_REFERER='/').post( "/", dict(pk_1='', pk_2='', a='0', b='changed')), table=TestTable(data=Foo.objects.all())) assert [(x.pk, x.a, x.b) for x in Foo.objects.all()] == [ (1, 0, u'changed'), (2, 0, u'changed'), (3, 3, u''), (4, 4, u''), ]
def test_bulk_edit(): assert Foo.objects.all().count() == 0 Foo(a=1, b="").save() Foo(a=2, b="").save() Foo(a=3, b="").save() Foo(a=4, b="").save() class TestTable(Table): a = Column.number( sortable=False, bulk__show=True ) # turn off sorting to not get the link with random query params b = Column(bulk__show=True) result = render_table( request=RequestFactory(HTTP_REFERER="/").get("/", dict(pk_1="", pk_2="", a="0", b="changed")), table=TestTable(data=Foo.objects.all()), ) assert '<form method="post" action=".">' in result assert '<input type="submit" class="button" value="Bulk change"/>' in result render_table( request=RequestFactory(HTTP_REFERER="/").post("/", dict(pk_1="", pk_2="", a="0", b="changed")), table=TestTable(data=Foo.objects.all()), ) assert [(x.pk, x.a, x.b) for x in Foo.objects.all()] == [ (1, 0, "changed"), (2, 0, "changed"), (3, 3, ""), (4, 4, ""), ]
def test_ajax_endpoint_namespacing(): class TestTable(Table): class Meta: endpoint_dispatch_prefix = "foo" endpoint__bar = lambda **_: 17 baz = Column() result = render_table(request=RequestFactory().get("/", {"__not_foo__bar": ""}), table=TestTable(data=[])) assert result is None result = render_table(request=RequestFactory().get("/", {"__foo__bar": ""}), table=TestTable(data=[])) assert 17 == json.loads(result.content.decode("utf8"))
def test_ajax_custom_endpoint(): class TestTable(Table): class Meta: endpoint__foo = lambda table, key, value: dict(baz=value) spam = Column() result = render_table(request=RequestFactory().get("/", {'__foo': 'bar'}), table=TestTable(data=[])) assert json.loads(result.content.decode('utf8')) == dict(baz='bar')
def test_ajax_endpoint_empty_response(): class TestTable(Table): class Meta: endpoint__foo = lambda **_: [] bar = Column() result = render_table(request=RequestFactory().get("/", {"__foo": ""}), table=TestTable(data=[])) assert [] == json.loads(result.content.decode("utf8"))
def test_ajax_custom_endpoint(): class TestTable(Table): class Meta: endpoint__foo = lambda table, key, value: dict(baz=value) spam = Column() result = render_table(request=RequestFactory().get("/", {'__foo': 'bar'}), table=TestTable(data=[])) assert json.loads(result.content.decode('utf8')) == dict(baz='bar')
def test_ajax_data_endpoint(): class TestTable(Table): class Meta: endpoint__data = lambda table, key, value: [ {cell.bound_column.name: cell.value for cell in row} for row in table ] foo = Column() bar = Column() table = TestTable(data=[Struct(foo=1, bar=2), Struct(foo=3, bar=4)]) result = render_table(request=RequestFactory().get("/", {"__data": ""}), table=table) assert json.loads(result.content.decode("utf8")) == [dict(foo=1, bar=2), dict(foo=3, bar=4)]
def verify_table_html(table, expected_html, query=None, find=None, links=None): """ Verify that the table renders to the expected markup, modulo formatting """ if find is None: find = dict(class_='listview') if not expected_html.strip(): expected_html = "<table/>" request = RequestFactory().get("/", query) request.user = AnonymousUser() actual_html = render_table(request=request, table=table, links=links) prettified_actual = reindent(BeautifulSoup(actual_html).find(**find).prettify()).strip() prettified_expected = reindent(BeautifulSoup(expected_html).find(**find).prettify()).strip() assert prettified_expected == prettified_actual
def test_ajax_endpoint(): f1 = Foo.objects.create(a=17, b="Hej") f2 = Foo.objects.create(a=42, b="Hopp") Bar(foo=f1, c=True).save() Bar(foo=f2, c=False).save() class TestTable(Table): foo = Column.choice_queryset( model=Foo, choices=lambda table, column: Foo.objects.all(), query__gui__extra__endpoint_attr='b', query__show=True, bulk__show=True, query__gui__show=True) result = render_table(request=RequestFactory().get("/", {'__query__gui__field__foo': 'hopp'}), table=TestTable(data=Bar.objects.all())) assert json.loads(result.content.decode('utf8')) == [{'id': 2, 'text': 'Hopp'}]
def test_ajax_data_endpoint(): class TestTable(Table): class Meta: endpoint__data = lambda table, key, value: [{ cell.bound_column.name: cell.value for cell in row } for row in table] foo = Column() bar = Column() table = TestTable(data=[ Struct(foo=1, bar=2), Struct(foo=3, bar=4), ]) result = render_table(request=RequestFactory().get("/", {'__data': ''}), table=table) assert json.loads(result.content.decode('utf8')) == [ dict(foo=1, bar=2), dict(foo=3, bar=4) ]
def test_ajax_endpoint(): f1 = Foo.objects.create(a=17, b="Hej") f2 = Foo.objects.create(a=42, b="Hopp") Bar(foo=f1, c=True).save() Bar(foo=f2, c=False).save() class TestTable(Table): foo = Column.choice_queryset( model=Foo, choices=lambda table, column, **_: Foo.objects.all(), query__gui__extra__endpoint_attr="b", query__show=True, bulk__show=True, query__gui__show=True, ) result = render_table( request=RequestFactory().get("/", {"__query__gui__field__foo": "hopp"}), table=TestTable(data=Bar.objects.all()) ) assert json.loads(result.content.decode("utf8")) == [{"id": 2, "text": "Hopp"}]
def verify_table_html(expected_html, query=None, find=None, links=None, **kwargs): """ Verify that the table renders to the expected markup, modulo formatting """ if find is None: find = dict(class_='listview') if not expected_html.strip(): expected_html = "<table/>" request = RequestFactory().get("/", query) request.user = AnonymousUser() actual_html = render_table(request=request, links=links, **kwargs) prettified_actual = reindent( BeautifulSoup(actual_html).find(**find).prettify()).strip() prettified_expected = reindent( BeautifulSoup(expected_html).find(**find).prettify()).strip() assert prettified_expected == prettified_actual
def test_ajax_endpoint(): f1 = Foo.objects.create(a=17, b="Hej") f2 = Foo.objects.create(a=42, b="Hopp") Bar(foo=f1, c=True).save() Bar(foo=f2, c=False).save() class TestTable(Table): foo = Column.choice_queryset( model=Foo, choices=lambda table, column: Foo.objects.all(), query__gui__extra__endpoint_attr='b', query__show=True, bulk__show=True, query__gui__show=True) result = render_table(request=RequestFactory().get( "/", {'__query__gui__field__foo': 'hopp'}), table=TestTable(data=Bar.objects.all())) assert json.loads(result.content.decode('utf8')) == [{ 'id': 2, 'text': 'Hopp' }]
def render_room(request, room_pk, **kwargs): # TODO: @dispatch on this view, and params to be able to customize rendering of the room room = get_object_or_404(Room, pk=room_pk) user_time = get_user_time(user=request.user, identifier=f'forum/room:{room.pk}') show_hidden = bool_parse(request.GET.get('show_hidden', '0')) def unread_from_here_href(row: Message, **_): params = request.GET.copy() params.setlist('unread_from_here', [row.last_changed_time.isoformat()]) return mark_safe('?' + params.urlencode() + "&") if 'time' in request.GET: unread2_time = datetime.fromisoformat(request.GET['time']) else: unread2_time = datetime.now() # NOTE: there's a set_user_time at the very bottom of this function if 'unread_from_here' in request.GET: user_time = datetime.fromisoformat(request.GET['unread_from_here']) # TODO: show many pages at once if unread? Right now we show the first unread page. start_page = None if 'page' not in request.GET: # Find first unread page try: first_unread_message = Message.objects.filter( room=room, last_changed_time__gte=user_time).order_by('path')[0] messages_before_first_unread = room.message_set.filter( path__lt=first_unread_message.path).count() start_page = messages_before_first_unread // PAGE_SIZE except IndexError: pass messages = Message.objects.filter(room__pk=room_pk).prefetch_related( 'user', 'room') if not show_hidden: messages = messages.filter(visible=True) def is_unread(row, **_): return row.last_changed_time >= user_time def is_unread2(row, **_): return row.last_changed_time >= unread2_time and not is_unread(row=row) def preprocess_data(data, table, **_): data = list(data) first_new = None for d in data: if is_unread(row=d): first_new = d break table.extra.unread = first_new is not None first_new_or_last_message = first_new if first_new_or_last_message is None and data: first_new_or_last_message = data[-1] if first_new_or_last_message is not None: # This is used by the view first_new_or_last_message.first_new = True return data result = render_table( request, template=get_template('forum/room.html'), paginator=RoomPaginator(messages), context=dict( obj=room, # required for header.html room=room, show_hidden=show_hidden, time=unread2_time or user_time, is_subscribed=is_subscribed(user=request.user, identifier=f'forum/room:{room.pk}'), is_mobile=request.user_agent.is_mobile, **kwargs, ), table__data=messages, table__exclude=['path'], table__extra_fields=[ Column(name='unread_from_here_href', attr=None, cell__value=unread_from_here_href), ], table__preprocess_data=preprocess_data, table__header__template=Template(''), table__row__template=get_template('forum/message.html'), table__row__attrs=dict( class__indent_0=lambda row, **_: row.indent == 0, class__message=True, class__current_user=lambda row, **_: request.user == row.user, class__other_user=lambda row, **_: request.user != row.user, class__unread=is_unread, class__unread2=is_unread2, ), table__attrs__cellpadding='0', table__attrs__cellspacing='0', table__attrs__id='first_newtable', table__attrs__align='center', table__attrs__class__roomtable=True, table__paginator__template='forum/blank.html', page=start_page, ) if 'unread_from_here' not in request.GET: user_time = datetime.now() set_user_time(user=request.user, identifier=f'forum/room:{room.pk}', time=user_time) return result