Repository: matrix-org/synapse

Issue:
Admin `list-room` API returns integers instead of booleans on SQLite
### Description

According to https://github.com/ruma/synapse-admin-api/issues/14, the `federatable` and `public` fields in the response of the [List room API](https://matrix-org.github.io/synapse/develop/admin_api/rooms.html#list-room-api) return `0` / `1` instead of `true` / `false`, while the example in the linked documentation shows boolean values.

### Steps to reproduce

Use the list room API? 🤷🏼 

### Homeserver

any

### Synapse Version

unknown

### Installation Method

_No response_

### Platform

unknown

### Relevant log output

```shell
-
```


### Anything else that would be useful to know?

_No response_


Discussion:
Is the server you are querying using a sqlite database rather than postgres?
I haven't reproduced this myself, just carried over the bug report in https://github.com/ruma/synapse-admin-api/issues/14. @avp90 can you answer?
Yes in my test case it's a SQLite database.

Resolving patch:
diff --git a/synapse/storage/databases/main/room.py b/synapse/storage/databases/main/room.py
--- a/synapse/storage/databases/main/room.py
+++ b/synapse/storage/databases/main/room.py
@@ -641,8 +641,10 @@ def _get_rooms_paginate_txn(
                         "version": room[5],
                         "creator": room[6],
                         "encryption": room[7],
-                        "federatable": room[8],
-                        "public": room[9],
+                        # room_stats_state.federatable is an integer on sqlite.
+                        "federatable": bool(room[8]),
+                        # rooms.is_public is an integer on sqlite.
+                        "public": bool(room[9]),
                         "join_rules": room[10],
                         "guest_access": room[11],
                         "history_visibility": room[12],


Test patch:
diff --git a/tests/rest/admin/test_room.py b/tests/rest/admin/test_room.py
--- a/tests/rest/admin/test_room.py
+++ b/tests/rest/admin/test_room.py
@@ -1080,7 +1080,9 @@ def test_list_rooms(self) -> None:
         room_ids = []
         for _ in range(total_rooms):
             room_id = self.helper.create_room_as(
-                self.admin_user, tok=self.admin_user_tok
+                self.admin_user,
+                tok=self.admin_user_tok,
+                is_public=True,
             )
             room_ids.append(room_id)
 
@@ -1119,8 +1121,8 @@ def test_list_rooms(self) -> None:
             self.assertIn("version", r)
             self.assertIn("creator", r)
             self.assertIn("encryption", r)
-            self.assertIn("federatable", r)
-            self.assertIn("public", r)
+            self.assertIs(r["federatable"], True)
+            self.assertIs(r["public"], True)
             self.assertIn("join_rules", r)
             self.assertIn("guest_access", r)
             self.assertIn("history_visibility", r)
@@ -1587,8 +1589,12 @@ def test_search_term_non_ascii(self) -> None:
     def test_single_room(self) -> None:
         """Test that a single room can be requested correctly"""
         # Create two test rooms
-        room_id_1 = self.helper.create_room_as(self.admin_user, tok=self.admin_user_tok)
-        room_id_2 = self.helper.create_room_as(self.admin_user, tok=self.admin_user_tok)
+        room_id_1 = self.helper.create_room_as(
+            self.admin_user, tok=self.admin_user_tok, is_public=True
+        )
+        room_id_2 = self.helper.create_room_as(
+            self.admin_user, tok=self.admin_user_tok, is_public=False
+        )
 
         room_name_1 = "something"
         room_name_2 = "else"
@@ -1634,7 +1640,10 @@ def test_single_room(self) -> None:
         self.assertIn("state_events", channel.json_body)
         self.assertIn("room_type", channel.json_body)
         self.assertIn("forgotten", channel.json_body)
+
         self.assertEqual(room_id_1, channel.json_body["room_id"])
+        self.assertIs(True, channel.json_body["federatable"])
+        self.assertIs(True, channel.json_body["public"])
 
     def test_single_room_devices(self) -> None:
         """Test that `joined_local_devices` can be requested correctly"""