mirror of
https://github.com/zulip/zulip.git
synced 2025-11-07 15:33:30 +00:00
@@ -137,6 +137,52 @@ casper.waitWhileSelector('.emoji_row', function () {
|
|||||||
casper.test.assertDoesntExist('.emoji_row');
|
casper.test.assertDoesntExist('.emoji_row');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function get_suggestions(str) {
|
||||||
|
casper.then(function () {
|
||||||
|
casper.evaluate(function (str) {
|
||||||
|
$('.create_default_stream')
|
||||||
|
.focus()
|
||||||
|
.val(str)
|
||||||
|
.trigger($.Event('keyup', { which: 0 }));
|
||||||
|
}, str);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function select_from_suggestions(item) {
|
||||||
|
casper.then(function () {
|
||||||
|
casper.evaluate(function (item) {
|
||||||
|
var tah = $('.create_default_stream').data().typeahead;
|
||||||
|
tah.mouseenter({
|
||||||
|
currentTarget: $('.typeahead:visible li:contains("'+item+'")')[0]
|
||||||
|
});
|
||||||
|
tah.select();
|
||||||
|
}, {item: item});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test default stream creation and addition
|
||||||
|
casper.then(function () {
|
||||||
|
casper.click('#settings-dropdown');
|
||||||
|
casper.click('a[href^="#subscriptions"]');
|
||||||
|
casper.click('#settings-dropdown');
|
||||||
|
casper.click('a[href^="#administration"]');
|
||||||
|
var stream_name = "Scotland";
|
||||||
|
// It matches with all the stream names which has 'O' as a substring (Rome, Scotland, Verona etc).
|
||||||
|
// I used 'O' to make sure that it works even if there are multiple suggestions.
|
||||||
|
// Capital 'O' is used instead of small 'o' to make sure that the suggestions are not case sensitive.
|
||||||
|
get_suggestions("O");
|
||||||
|
select_from_suggestions(stream_name);
|
||||||
|
casper.waitForSelector('.default_stream_row[id='+stream_name+']', function () {
|
||||||
|
casper.test.assertSelectorHasText('.default_stream_row[id='+stream_name+'] .default_stream_name', stream_name);
|
||||||
|
});
|
||||||
|
casper.waitForSelector('.default_stream_row[id='+stream_name+']', function () {
|
||||||
|
casper.test.assertSelectorHasText('.default_stream_row[id='+stream_name+'] .default_stream_name', stream_name);
|
||||||
|
casper.click('.default_stream_row[id='+stream_name+'] button.remove-default-stream');
|
||||||
|
});
|
||||||
|
casper.waitWhileSelector('.default_stream_row[id='+stream_name+']', function () {
|
||||||
|
casper.test.assertDoesntExist('.default_stream_row[id='+stream_name+']');
|
||||||
|
});
|
||||||
|
});
|
||||||
// TODO: Test stream deletion
|
// TODO: Test stream deletion
|
||||||
|
|
||||||
common.then_log_out();
|
common.then_log_out();
|
||||||
|
|||||||
@@ -86,6 +86,19 @@ function render(template_name, args) {
|
|||||||
global.write_test_output("admin_tab.handlebars", html);
|
global.write_test_output("admin_tab.handlebars", html);
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
(function admin_default_streams_list() {
|
||||||
|
var html = '<table>';
|
||||||
|
var streams = ['devel', 'trac', 'zulip'];
|
||||||
|
_.each(streams, function (stream) {
|
||||||
|
var args = {stream: {name: stream, invite_only: false}};
|
||||||
|
html += render('admin_default_streams_list', args);
|
||||||
|
});
|
||||||
|
html += "</table>";
|
||||||
|
var span = $(html).find(".default_stream_name:first");
|
||||||
|
assert.equal(span.text(), "devel");
|
||||||
|
global.write_test_output("admin_default_streams_list.handlebars", html);
|
||||||
|
}());
|
||||||
|
|
||||||
(function admin_streams_list() {
|
(function admin_streams_list() {
|
||||||
var html = '<table>';
|
var html = '<table>';
|
||||||
var streams = ['devel', 'trac', 'zulip'];
|
var streams = ['devel', 'trac', 'zulip'];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
var admin = (function () {
|
var admin = (function () {
|
||||||
|
|
||||||
var exports = {};
|
var exports = {};
|
||||||
|
var all_streams = [];
|
||||||
|
|
||||||
exports.show_or_hide_menu_item = function () {
|
exports.show_or_hide_menu_item = function () {
|
||||||
var item = $('.admin-menu-item').expectOne();
|
var item = $('.admin-menu-item').expectOne();
|
||||||
@@ -67,6 +68,7 @@ function populate_users (realm_people_data) {
|
|||||||
|
|
||||||
function populate_streams (streams_data) {
|
function populate_streams (streams_data) {
|
||||||
var streams_table = $("#admin_streams_table").expectOne();
|
var streams_table = $("#admin_streams_table").expectOne();
|
||||||
|
all_streams = streams_data;
|
||||||
streams_table.find("tr.stream_row").remove();
|
streams_table.find("tr.stream_row").remove();
|
||||||
_.each(streams_data.streams, function (stream) {
|
_.each(streams_data.streams, function (stream) {
|
||||||
streams_table.append(templates.render("admin_streams_list", {stream: stream}));
|
streams_table.append(templates.render("admin_streams_list", {stream: stream}));
|
||||||
@@ -74,6 +76,55 @@ function populate_streams (streams_data) {
|
|||||||
loading.destroy_indicator($('#admin_page_streams_loading_indicator'));
|
loading.destroy_indicator($('#admin_page_streams_loading_indicator'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function populate_default_streams(streams_data) {
|
||||||
|
var default_streams_table = $("#admin_default_streams_table").expectOne();
|
||||||
|
_.each(streams_data, function (stream) {
|
||||||
|
default_streams_table.append(templates.render("admin_default_streams_list", {stream: stream}));
|
||||||
|
});
|
||||||
|
loading.destroy_indicator($('#admin_page_default_streams_loading_indicator'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_non_default_streams_names(streams_data) {
|
||||||
|
var non_default_streams_names = [];
|
||||||
|
var default_streams_names = [];
|
||||||
|
|
||||||
|
_.each(page_params.realm_default_streams, function (default_stream) {
|
||||||
|
default_streams_names.push(default_stream.name);
|
||||||
|
});
|
||||||
|
|
||||||
|
_.each(streams_data.streams, function (stream) {
|
||||||
|
if (default_streams_names.indexOf(stream.name) < 0) {
|
||||||
|
non_default_streams_names.push(stream.name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return non_default_streams_names;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.update_default_streams_table = function () {
|
||||||
|
$("#admin_default_streams_table").expectOne().find("tr.default_stream_row").remove();
|
||||||
|
populate_default_streams(page_params.realm_default_streams);
|
||||||
|
};
|
||||||
|
|
||||||
|
function make_stream_default(stream_name) {
|
||||||
|
var data = {
|
||||||
|
stream_name: stream_name
|
||||||
|
};
|
||||||
|
var default_streams_table = $("#admin_default_streams_table").expectOne();
|
||||||
|
|
||||||
|
channel.put({
|
||||||
|
url: '/json/default_streams',
|
||||||
|
data: data,
|
||||||
|
error: function (xhr, error_type) {
|
||||||
|
if (xhr.status.toString().charAt(0) === "4") {
|
||||||
|
$(".active_stream_row button").closest("td").html(
|
||||||
|
$("<p>").addClass("text-error").text($.parseJSON(xhr.responseText).msg));
|
||||||
|
} else {
|
||||||
|
$(".active_stream_row button").text("Failed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
exports.populate_emoji = function (emoji_data) {
|
exports.populate_emoji = function (emoji_data) {
|
||||||
var emoji_table = $('#admin_emoji_table').expectOne();
|
var emoji_table = $('#admin_emoji_table').expectOne();
|
||||||
emoji_table.find('tr.emoji_row').remove();
|
emoji_table.find('tr.emoji_row').remove();
|
||||||
@@ -123,7 +174,7 @@ exports.setup_page = function () {
|
|||||||
|
|
||||||
// Populate streams table
|
// Populate streams table
|
||||||
channel.get({
|
channel.get({
|
||||||
url: '/json/streams?include_public=true&include_subscribed=true',
|
url: '/json/streams?include_public=true&include_subscribed=true&include_default=true',
|
||||||
timeout: 10*1000,
|
timeout: 10*1000,
|
||||||
idempotent: true,
|
idempotent: true,
|
||||||
success: populate_streams,
|
success: populate_streams,
|
||||||
@@ -132,6 +183,7 @@ exports.setup_page = function () {
|
|||||||
|
|
||||||
// Populate emoji table
|
// Populate emoji table
|
||||||
exports.populate_emoji(page_params.realm_emoji);
|
exports.populate_emoji(page_params.realm_emoji);
|
||||||
|
exports.update_default_streams_table();
|
||||||
|
|
||||||
// Setup click handlers
|
// Setup click handlers
|
||||||
$(".admin_user_table").on("click", ".deactivate", function (e) {
|
$(".admin_user_table").on("click", ".deactivate", function (e) {
|
||||||
@@ -164,6 +216,51 @@ exports.setup_page = function () {
|
|||||||
$("#deactivation_stream_modal").modal("show");
|
$("#deactivation_stream_modal").modal("show");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(".admin_default_stream_table").on("click", ".remove-default-stream", function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
$(".active_default_stream_row").removeClass("active_default_stream_row");
|
||||||
|
var row = $(e.target).closest(".default_stream_row");
|
||||||
|
row.addClass("active_default_stream_row");
|
||||||
|
var stream_name = row.find('.default_stream_name').text();
|
||||||
|
|
||||||
|
channel.del({
|
||||||
|
url: '/json/default_streams'+ '?' + $.param({"stream_name": stream_name}),
|
||||||
|
error: function (xhr, error_type) {
|
||||||
|
if (xhr.status.toString().charAt(0) === "4") {
|
||||||
|
$(".active_default_stream_row button").closest("td").html(
|
||||||
|
$("<p>").addClass("text-error").text($.parseJSON(xhr.responseText).msg));
|
||||||
|
} else {
|
||||||
|
$(".active_default_stream_row button").text("Failed!");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
success: function () {
|
||||||
|
var row = $(".active_default_stream_row");
|
||||||
|
row.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.create_default_stream').keypress(function (e) {
|
||||||
|
if (e.which === 13) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.create_default_stream').typeahead({
|
||||||
|
items: 5,
|
||||||
|
fixed: true,
|
||||||
|
source: function (query) {
|
||||||
|
return get_non_default_streams_names(all_streams);
|
||||||
|
},
|
||||||
|
highlight: true,
|
||||||
|
updater: function (stream_name) {
|
||||||
|
make_stream_default(stream_name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
$(".admin_bot_table").on("click", ".deactivate", function (e) {
|
$(".admin_bot_table").on("click", ".deactivate", function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|||||||
@@ -119,8 +119,13 @@ function get_events_success(events) {
|
|||||||
if (event.op === 'update') {
|
if (event.op === 'update') {
|
||||||
// Legacy: Stream properties are still managed by subs.js on the client side.
|
// Legacy: Stream properties are still managed by subs.js on the client side.
|
||||||
subs.update_subscription_properties(event.name, event.property, event.value);
|
subs.update_subscription_properties(event.name, event.property, event.value);
|
||||||
|
admin.update_default_streams_table();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'default_streams':
|
||||||
|
page_params.realm_default_streams = event.default_streams;
|
||||||
|
admin.update_default_streams_table();
|
||||||
|
break;
|
||||||
case 'subscription':
|
case 'subscription':
|
||||||
if (event.op === 'add') {
|
if (event.op === 'add') {
|
||||||
_.each(event.subscriptions, function (sub) {
|
_.each(event.subscriptions, function (sub) {
|
||||||
|
|||||||
@@ -3246,7 +3246,8 @@ div.edit_bot {
|
|||||||
|
|
||||||
.edit_bot_form .control-label,
|
.edit_bot_form .control-label,
|
||||||
#create_bot_form .control-label,
|
#create_bot_form .control-label,
|
||||||
.admin-emoji-form .control-label {
|
.admin-emoji-form .control-label,
|
||||||
|
.default-stream-form .control-label {
|
||||||
width: 10em;
|
width: 10em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
@@ -3501,7 +3502,8 @@ div.edit_bot {
|
|||||||
|
|
||||||
#settings .bot-information-box,
|
#settings .bot-information-box,
|
||||||
#settings .add-new-bot-box,
|
#settings .add-new-bot-box,
|
||||||
#emoji-settings .add-new-emoji-box {
|
#emoji-settings .add-new-emoji-box,
|
||||||
|
#admin-default-streams-list .add-new-default-stream-box{
|
||||||
background: #e3e3e3;
|
background: #e3e3e3;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-left: 38px;
|
margin-left: 38px;
|
||||||
@@ -3513,10 +3515,17 @@ div.edit_bot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#settings .add-new-bot-box,
|
#settings .add-new-bot-box,
|
||||||
#emoji-settings .add-new-emoji-box {
|
#emoji-settings .add-new-emoji-box,
|
||||||
|
#admin-default-streams-list .add-new-default-stream-box {
|
||||||
background: #cbe3cb;
|
background: #cbe3cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.new-default-stream-section-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 300;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
#settings #get_api_key_box,
|
#settings #get_api_key_box,
|
||||||
#settings #show_api_key_box,
|
#settings #show_api_key_box,
|
||||||
#settings #api_key_button_box .control-group {
|
#settings #api_key_button_box .control-group {
|
||||||
|
|||||||
13
static/templates/admin_default_streams_list.handlebars
Normal file
13
static/templates/admin_default_streams_list.handlebars
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{{#with stream}}
|
||||||
|
<tr class="default_stream_row" id="{{name}}">
|
||||||
|
<td>
|
||||||
|
{{#if invite_only}}<i class="icon-vector-lock "></i>{{/if}}
|
||||||
|
<span class="default_stream_name">{{name}}</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn remove-default-stream btn-danger">
|
||||||
|
{{t "Remove from default" }}
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/with}}
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
<li role="presentation">
|
<li role="presentation">
|
||||||
<a href="#streams" aria-controls="streams" role="tab" data-toggle="tab"><i class="icon-vector-exchange settings-section-icon"></i> {{t "Streams Deletion" }}</a>
|
<a href="#streams" aria-controls="streams" role="tab" data-toggle="tab"><i class="icon-vector-exchange settings-section-icon"></i> {{t "Streams Deletion" }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li role="presentation">
|
||||||
|
<a href="#default-streams" aria-controls="default-streams" role="tab" data-toggle="tab"><i class="icon-vector-exchange settings-section-icon"></i> {{t "Default Streams" }}</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content">
|
<div class="tab-content">
|
||||||
<div role="tabpanel" class="tab-pane active" id="organization">
|
<div role="tabpanel" class="tab-pane active" id="organization">
|
||||||
@@ -163,6 +166,31 @@
|
|||||||
<div id="admin_page_streams_loading_indicator"></div>
|
<div id="admin_page_streams_loading_indicator"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="default-streams">
|
||||||
|
<div id="admin-default-streams-list" class="settings-section">
|
||||||
|
<div class="settings-section-title"><i class="icon-vector-exchange settings-section-icon"></i>
|
||||||
|
{{t "Default Streams"}}</div>
|
||||||
|
<div class="admin-table-wrapper">
|
||||||
|
<p>{{#tr this}}Configure the default streams new users are subscribed to when joining the {{domain}} organization.{{/tr}}</p>
|
||||||
|
<table class="table table-condensed table-striped">
|
||||||
|
<tbody id="admin_default_streams_table" class="admin_default_stream_table">
|
||||||
|
<th>{{t "Name" }}</th>
|
||||||
|
<th class="actions">{{t "Actions" }}</th>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div id="admin_page_default_streams_loading_indicator"></div>
|
||||||
|
<form class="form-horizontal default-stream-form">
|
||||||
|
<div class="add-new-default-stream-box">
|
||||||
|
<div class="new-default-stream-section-title">{{t "Add New Default Stream" }}</div>
|
||||||
|
<div class="control-group" id="default_stream_inputs">
|
||||||
|
<label for="default_stream_name" class="control-label">{{t "Stream Name" }}</label>
|
||||||
|
<input class="create_default_stream" type="text" placeholder="{{t "Stream Name" }}" name="stream_name" autocomplete="off"></input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="deactivation_user_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="deactivation_user_modal_label" aria-hidden="true">
|
<div id="deactivation_user_modal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="deactivation_user_modal_label" aria-hidden="true">
|
||||||
|
|||||||
@@ -2025,11 +2025,21 @@ def set_default_streams(realm, stream_names):
|
|||||||
'domain': realm.domain,
|
'domain': realm.domain,
|
||||||
'streams': stream_names})
|
'streams': stream_names})
|
||||||
|
|
||||||
|
|
||||||
|
def notify_default_streams(realm):
|
||||||
|
# type: (Realm) -> None
|
||||||
|
event = dict(
|
||||||
|
type="default_streams",
|
||||||
|
default_streams=streams_to_dicts_sorted(get_default_streams_for_realm(realm))
|
||||||
|
)
|
||||||
|
send_event(event, active_user_ids(realm))
|
||||||
|
|
||||||
def do_add_default_stream(realm, stream_name):
|
def do_add_default_stream(realm, stream_name):
|
||||||
# type: (Realm, text_type) -> None
|
# type: (Realm, text_type) -> None
|
||||||
stream, _ = create_stream_if_needed(realm, stream_name)
|
stream, _ = create_stream_if_needed(realm, stream_name)
|
||||||
if not DefaultStream.objects.filter(realm=realm, stream=stream).exists():
|
if not DefaultStream.objects.filter(realm=realm, stream=stream).exists():
|
||||||
DefaultStream.objects.create(realm=realm, stream=stream)
|
DefaultStream.objects.create(realm=realm, stream=stream)
|
||||||
|
notify_default_streams(realm)
|
||||||
|
|
||||||
def do_remove_default_stream(realm, stream_name):
|
def do_remove_default_stream(realm, stream_name):
|
||||||
# type: (Realm, text_type) -> None
|
# type: (Realm, text_type) -> None
|
||||||
@@ -2037,6 +2047,7 @@ def do_remove_default_stream(realm, stream_name):
|
|||||||
if stream is None:
|
if stream is None:
|
||||||
raise JsonableError(_("Stream does not exist"))
|
raise JsonableError(_("Stream does not exist"))
|
||||||
DefaultStream.objects.filter(realm=realm, stream=stream).delete()
|
DefaultStream.objects.filter(realm=realm, stream=stream).delete()
|
||||||
|
notify_default_streams(realm)
|
||||||
|
|
||||||
def get_default_streams_for_realm(realm):
|
def get_default_streams_for_realm(realm):
|
||||||
# type: (Realm) -> List[Stream]
|
# type: (Realm) -> List[Stream]
|
||||||
@@ -2049,6 +2060,11 @@ def get_default_subs(user_profile):
|
|||||||
# to some day further customize how we set up default streams for new users.
|
# to some day further customize how we set up default streams for new users.
|
||||||
return get_default_streams_for_realm(user_profile.realm)
|
return get_default_streams_for_realm(user_profile.realm)
|
||||||
|
|
||||||
|
# returns default streams in json serializeable format
|
||||||
|
def streams_to_dicts_sorted(streams):
|
||||||
|
# type: (List[Stream]) -> List[Dict[str, Any]]
|
||||||
|
return sorted([stream.to_dict() for stream in streams], key=lambda elt: elt["name"])
|
||||||
|
|
||||||
def do_update_user_activity_interval(user_profile, log_time):
|
def do_update_user_activity_interval(user_profile, log_time):
|
||||||
# type: (UserProfile, datetime.datetime) -> None
|
# type: (UserProfile, datetime.datetime) -> None
|
||||||
effective_end = log_time + datetime.timedelta(minutes=15)
|
effective_end = log_time + datetime.timedelta(minutes=15)
|
||||||
@@ -2687,6 +2703,8 @@ def fetch_initial_state_data(user_profile, event_types, queue_id):
|
|||||||
|
|
||||||
if want('stream'):
|
if want('stream'):
|
||||||
state['streams'] = do_get_streams(user_profile)
|
state['streams'] = do_get_streams(user_profile)
|
||||||
|
if want('default_streams'):
|
||||||
|
state['realm_default_streams'] = streams_to_dicts_sorted(get_default_streams_for_realm(user_profile.realm))
|
||||||
|
|
||||||
if want('update_display_settings'):
|
if want('update_display_settings'):
|
||||||
state['twenty_four_hour_time'] = user_profile.twenty_four_hour_time
|
state['twenty_four_hour_time'] = user_profile.twenty_four_hour_time
|
||||||
@@ -2760,6 +2778,8 @@ def apply_events(state, events, user_profile):
|
|||||||
elif event['op'] == "vacate":
|
elif event['op'] == "vacate":
|
||||||
stream_ids = [s["stream_id"] for s in event['streams']]
|
stream_ids = [s["stream_id"] for s in event['streams']]
|
||||||
state['streams'] = [s for s in state['streams'] if s["stream_id"] not in stream_ids]
|
state['streams'] = [s for s in state['streams'] if s["stream_id"] not in stream_ids]
|
||||||
|
elif event['type'] == 'default_streams':
|
||||||
|
state['realm_default_streams'] = event['default_streams']
|
||||||
elif event['type'] == 'realm':
|
elif event['type'] == 'realm':
|
||||||
field = 'realm_' + event['property']
|
field = 'realm_' + event['property']
|
||||||
state[field] = event['value']
|
state[field] = event['value']
|
||||||
@@ -3167,8 +3187,8 @@ def get_occupied_streams(realm):
|
|||||||
return Stream.objects.filter(id__in=stream_ids, realm=realm, deactivated=False)
|
return Stream.objects.filter(id__in=stream_ids, realm=realm, deactivated=False)
|
||||||
|
|
||||||
def do_get_streams(user_profile, include_public=True, include_subscribed=True,
|
def do_get_streams(user_profile, include_public=True, include_subscribed=True,
|
||||||
include_all_active=False):
|
include_all_active=False, include_default=False):
|
||||||
# type: (UserProfile, bool, bool, bool) -> List[Dict[str, Any]]
|
# type: (UserProfile, bool, bool, bool, bool) -> List[Dict[str, Any]]
|
||||||
if include_all_active and not user_profile.is_api_super_user:
|
if include_all_active and not user_profile.is_api_super_user:
|
||||||
raise JsonableError(_("User not authorized for this query"))
|
raise JsonableError(_("User not authorized for this query"))
|
||||||
|
|
||||||
@@ -3199,6 +3219,13 @@ def do_get_streams(user_profile, include_public=True, include_subscribed=True,
|
|||||||
|
|
||||||
streams = [(row.to_dict()) for row in query]
|
streams = [(row.to_dict()) for row in query]
|
||||||
streams.sort(key=lambda elt: elt["name"])
|
streams.sort(key=lambda elt: elt["name"])
|
||||||
|
if include_default:
|
||||||
|
is_default = {}
|
||||||
|
default_streams = get_default_streams_for_realm(user_profile.realm)
|
||||||
|
for default_stream in default_streams:
|
||||||
|
is_default[default_stream.id] = True
|
||||||
|
for stream in streams:
|
||||||
|
stream['is_default'] = is_default.get(stream["stream_id"], False)
|
||||||
|
|
||||||
return streams
|
return streams
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ from zerver.lib.actions import (
|
|||||||
do_remove_realm_filter,
|
do_remove_realm_filter,
|
||||||
do_remove_subscription,
|
do_remove_subscription,
|
||||||
do_rename_stream,
|
do_rename_stream,
|
||||||
|
do_add_default_stream,
|
||||||
do_set_muted_topics,
|
do_set_muted_topics,
|
||||||
do_set_realm_create_stream_by_admins_only,
|
do_set_realm_create_stream_by_admins_only,
|
||||||
do_set_realm_name,
|
do_set_realm_name,
|
||||||
@@ -377,6 +378,21 @@ class EventsRegisterTest(AuthedTestCase):
|
|||||||
error = alert_words_checker('events[0]', events[0])
|
error = alert_words_checker('events[0]', events[0])
|
||||||
self.assert_on_error(error)
|
self.assert_on_error(error)
|
||||||
|
|
||||||
|
def test_default_streams_events(self):
|
||||||
|
default_streams_checker = check_dict([
|
||||||
|
('type', equals('default_streams')),
|
||||||
|
('default_streams', check_list(check_dict([
|
||||||
|
('description', check_string),
|
||||||
|
('invite_only', check_bool),
|
||||||
|
('name', check_string),
|
||||||
|
('stream_id', check_int),
|
||||||
|
]))),
|
||||||
|
])
|
||||||
|
|
||||||
|
events = self.do_test(lambda: do_add_default_stream(self.user_profile.realm, "Scotland"))
|
||||||
|
error = default_streams_checker('events[0]', events[0])
|
||||||
|
self.assert_on_error(error)
|
||||||
|
|
||||||
def test_muted_topics_events(self):
|
def test_muted_topics_events(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
muted_topics_checker = check_dict([
|
muted_topics_checker = check_dict([
|
||||||
@@ -387,7 +403,6 @@ class EventsRegisterTest(AuthedTestCase):
|
|||||||
error = muted_topics_checker('events[0]', events[0])
|
error = muted_topics_checker('events[0]', events[0])
|
||||||
self.assert_on_error(error)
|
self.assert_on_error(error)
|
||||||
|
|
||||||
|
|
||||||
def test_change_full_name(self):
|
def test_change_full_name(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
schema_checker = check_dict([
|
schema_checker = check_dict([
|
||||||
|
|||||||
@@ -862,6 +862,7 @@ def home(request):
|
|||||||
alert_words = register_ret['alert_words'],
|
alert_words = register_ret['alert_words'],
|
||||||
muted_topics = register_ret['muted_topics'],
|
muted_topics = register_ret['muted_topics'],
|
||||||
realm_filters = register_ret['realm_filters'],
|
realm_filters = register_ret['realm_filters'],
|
||||||
|
realm_default_streams = register_ret['realm_default_streams'],
|
||||||
is_admin = user_profile.is_realm_admin,
|
is_admin = user_profile.is_realm_admin,
|
||||||
can_create_streams = user_profile.can_create_streams(),
|
can_create_streams = user_profile.can_create_streams(),
|
||||||
name_changes_disabled = name_changes_disabled(user_profile.realm),
|
name_changes_disabled = name_changes_disabled(user_profile.realm),
|
||||||
|
|||||||
@@ -169,10 +169,16 @@ def json_make_stream_private(request, user_profile, stream_name=REQ()):
|
|||||||
@require_realm_admin
|
@require_realm_admin
|
||||||
@has_request_variables
|
@has_request_variables
|
||||||
def update_stream_backend(request, user_profile, stream_name,
|
def update_stream_backend(request, user_profile, stream_name,
|
||||||
description=REQ(validator=check_string, default=None)):
|
description=REQ(validator=check_string, default=None),
|
||||||
# type: (HttpRequest, UserProfile, str, Optional[str]) -> HttpResponse
|
is_default=REQ(validator=check_bool, default=None)):
|
||||||
|
# type: (HttpRequest, UserProfile, str, Optional[str], Optional[bool]) -> HttpResponse
|
||||||
if description is not None:
|
if description is not None:
|
||||||
do_change_stream_description(user_profile.realm, stream_name, description)
|
do_change_stream_description(user_profile.realm, stream_name, description)
|
||||||
|
if is_default is not None:
|
||||||
|
if is_default:
|
||||||
|
do_add_default_stream(user_profile.realm, stream_name)
|
||||||
|
else:
|
||||||
|
do_remove_default_stream(user_profile.realm, stream_name)
|
||||||
return json_success({})
|
return json_success({})
|
||||||
|
|
||||||
def list_subscriptions_backend(request, user_profile):
|
def list_subscriptions_backend(request, user_profile):
|
||||||
@@ -416,11 +422,15 @@ def json_get_subscribers(request, user_profile):
|
|||||||
def get_streams_backend(request, user_profile,
|
def get_streams_backend(request, user_profile,
|
||||||
include_public=REQ(validator=check_bool, default=True),
|
include_public=REQ(validator=check_bool, default=True),
|
||||||
include_subscribed=REQ(validator=check_bool, default=True),
|
include_subscribed=REQ(validator=check_bool, default=True),
|
||||||
include_all_active=REQ(validator=check_bool, default=False)):
|
include_all_active=REQ(validator=check_bool, default=False),
|
||||||
# type: (HttpRequest, UserProfile, bool, bool, bool) -> HttpResponse
|
include_default=REQ(validator=check_bool, default=False)):
|
||||||
|
# type: (HttpRequest, UserProfile, bool, bool, bool, bool) -> HttpResponse
|
||||||
|
|
||||||
streams = do_get_streams(user_profile, include_public, include_subscribed,
|
|
||||||
include_all_active)
|
streams = do_get_streams(user_profile, include_public=include_public,
|
||||||
|
include_subscribed=include_subscribed,
|
||||||
|
include_all_active=include_all_active,
|
||||||
|
include_default=include_default)
|
||||||
return json_success({"streams": streams})
|
return json_success({"streams": streams})
|
||||||
|
|
||||||
@authenticated_json_post_view
|
@authenticated_json_post_view
|
||||||
|
|||||||
Reference in New Issue
Block a user