Merge branch 'next-minor' into develop

This commit is contained in:
Benjamin Neff 2022-06-19 19:30:56 +02:00
commit 6c9e7f283f
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
22 changed files with 88 additions and 99 deletions

View file

@ -40,10 +40,12 @@ Although the chat was never enabled per default and was marked as experimental,
# 0.7.18.0 # 0.7.18.0
## Refactor ## Refactor
* Fix order-dependent jasmine test failures and switch to random order [#8333](https://github.com/diaspora/diaspora/pull/8333)
* Get rid of some uses of "execute_script" in feature specs [#8331](https://github.com/diaspora/diaspora/pull/8331)
## Bug fixes ## Bug fixes
## Bug fixes ## Features
# 0.7.17.0 # 0.7.17.0

View file

@ -19,12 +19,12 @@ Feature: Change settings
Scenario: Change my email preferences Scenario: Change my email preferences
When I uncheck "user_email_preferences_mentioned" When I uncheck "user_email_preferences_mentioned"
And I scroll a bit And I scroll to "change_email_preferences"
And I press "change_email_preferences" And I press "change_email_preferences"
Then I should see "Email notifications changed" Then I should see "Email notifications changed"
And the "user_email_preferences_mentioned" checkbox should not be checked And the "user_email_preferences_mentioned" checkbox should not be checked
When I uncheck "user_email_preferences_mentioned_in_comment" When I uncheck "user_email_preferences_mentioned_in_comment"
And I scroll a bit And I scroll to "change_email_preferences"
And I press "change_email_preferences" And I press "change_email_preferences"
Then I should see "Email notifications changed" Then I should see "Email notifications changed"
And the "user_email_preferences_mentioned_in_comment" checkbox should not be checked And the "user_email_preferences_mentioned_in_comment" checkbox should not be checked

View file

@ -173,14 +173,6 @@ Then /^I should see (\d+) contacts$/ do |n_posts|
has_css?("#people-stream .stream-element", count: n_posts.to_i).should be true has_css?("#people-stream .stream-element", count: n_posts.to_i).should be true
end end
When /^I scroll a bit$/ do
page.execute_script("window.scrollBy(0,200)")
end
And /^I scroll down$/ do
page.execute_script("window.scrollBy(0,3000000)")
end
Then /^I should have scrolled down$/ do Then /^I should have scrolled down$/ do
expect(page.evaluate_script("window.pageYOffset")).to be > 0 expect(page.evaluate_script("window.pageYOffset")).to be > 0
end end

View file

@ -24,7 +24,7 @@ And "I wait for notifications to load" do
end end
And "I scroll down on the notifications dropdown" do And "I scroll down on the notifications dropdown" do
page.execute_script("$('.notifications').scrollTop(350)") find(".notifications").scroll_to(0, 350)
end end
Then "the notification dropdown should be visible" do Then "the notification dropdown should be visible" do

View file

@ -13,9 +13,11 @@ Then /^the publisher should be expanded$/ do
end end
When /^I click to delete the first uploaded photo$/ do When /^I click to delete the first uploaded photo$/ do
page.execute_script("$('#photodropzone .x').css('display', 'block');")
image_count = all(".publisher_photo img", wait: false).count image_count = all(".publisher_photo img", wait: false).count
find("#photodropzone .x", match: :first).trigger "click" within "ul#photodropzone" do
first("img").hover
find(".x", match: :first).trigger "click"
end
page.assert_selector(".publisher_photo img", count: image_count - 1) page.assert_selector(".publisher_photo img", count: image_count - 1)
end end
@ -68,12 +70,6 @@ When /^I post an extremely long status message$/ do
end end
When /^I select "([^"]*)" on the aspect dropdown$/ do |text| When /^I select "([^"]*)" on the aspect dropdown$/ do |text|
page.execute_script( find("button.dropdown-toggle").click
"$('#publisher .dropdown .dropdown_list, #publisher .aspect-dropdown .dropdown-menu') find(".dropdown-menu li", text: text).click
.find('li').each(function(i,el){
var elem = $(el);
if ('" + text + "' == $.trim(elem.text()) ) {
elem.click();
}});"
)
end end

View file

@ -171,8 +171,8 @@ Then /^the "([^"]*)" bootstrap-switch should be (on|off)$/ do |label, state|
end end
end end
Then /^I toggle the "([^"]*)" bootstrap-switch$/ do |label| Then /^I toggle the "#([^"]*)" bootstrap-switch$/ do |id|
page.execute_script("return $('#{label}').bootstrapSwitch('toggleState')") find(".bootstrap-switch-id-#{id}").click
end end
Then /^(?:|I )should be on (.+)$/ do |page_name| Then /^(?:|I )should be on (.+)$/ do |page_name|
@ -196,3 +196,8 @@ Then /^I wait until ajax requests finished$/ do
loop until page.evaluate_script("jQuery.active") == 0 loop until page.evaluate_script("jQuery.active") == 0
end end
end end
When /^I scroll to "([^"]*)"$/ do |element_id|
element = find_by_id(element_id) # rubocop:disable Rails/DynamicFindBy
page.scroll_to(element, align: :bottom)
end

View file

@ -27,10 +27,10 @@ module PublishingCukeHelpers
end end
def upload_file_with_publisher(path) def upload_file_with_publisher(path)
page.execute_script(%q{$("input[name='qqfile']").css("opacity", '1');})
image_count = all(".publisher_photo img", wait: false).count image_count = all(".publisher_photo img", wait: false).count
with_scope("#publisher-textarea-wrapper") do with_scope("#publisher-textarea-wrapper") do
attach_file("qqfile", Rails.root.join(path).to_s) find('input[name="qqfile"]', visible: false)
.attach_file(Rails.root.join(path).to_s, make_visible: true)
# wait for the image to be ready # wait for the image to be ready
page.assert_selector(".publisher_photo.loading", count: 0) page.assert_selector(".publisher_photo.loading", count: 0)
page.assert_selector(".publisher_photo img", count: image_count + 1) page.assert_selector(".publisher_photo img", count: image_count + 1)

View file

@ -1,4 +1,8 @@
describe("app", function() { describe("app", function() {
beforeAll(function() {
Diaspora.I18n.load(spec.defaultLocale, "en");
});
afterAll(function() { afterAll(function() {
Backbone.history.stop(); Backbone.history.stop();
app.initialize(); app.initialize();
@ -33,6 +37,10 @@ describe("app", function() {
}); });
describe("user", function() { describe("user", function() {
beforeEach(function() {
logout();
});
it("returns false if the current_user isn't set", function() { it("returns false if the current_user isn't set", function() {
app._user = undefined; app._user = undefined;
expect(app.user()).toEqual(false); expect(app.user()).toEqual(false);

View file

@ -21,6 +21,7 @@ describe("app.collections.Contacts", function(){
}); });
it("should compare the username if app.aspect is not present", function() { it("should compare the username if app.aspect is not present", function() {
delete app.aspect;
expect(this.collection.comparator(this.con1, this.con3)).toBeLessThan(0); expect(this.collection.comparator(this.con1, this.con3)).toBeLessThan(0);
}); });

View file

@ -14,6 +14,12 @@ describe("app.collections.Notifications", function() {
it("initializes attributes", function() { it("initializes attributes", function() {
var target = new app.collections.Notifications(); var target = new app.collections.Notifications();
/* I don't know how backbone is working, but if I don't force reset the old values are kept from previous test */
if (target !== undefined) {
target.unreadCount = 0;
target.unreadCountByType = {};
}
/* end of force refresh */
expect(target.model).toBe(app.models.Notification); expect(target.model).toBe(app.models.Notification);
/* eslint-disable camelcase */ /* eslint-disable camelcase */
expect(target.url).toBe(Routes.notifications({per_page: 10, page: 1})); expect(target.url).toBe(Routes.notifications({per_page: 10, page: 1}));
@ -174,6 +180,12 @@ describe("app.collections.Notifications", function() {
describe("parse", function() { describe("parse", function() {
beforeEach(function() { beforeEach(function() {
this.target = new app.collections.Notifications(); this.target = new app.collections.Notifications();
/* I don't know how backbone is working, but if I don't force reset the old values are kept from previous test */
if (this.target !== undefined) {
this.target.unreadCount = 0;
this.target.unreadCountByType = {};
}
/* end of force refresh */
}); });
it("sets the unreadCount and unreadCountByType attributes", function() { it("sets the unreadCount and unreadCountByType attributes", function() {

View file

@ -122,9 +122,11 @@ describe("app.models.Post.Interactions", function(){
}); });
it("adds the reshare to the default, activity and aspects stream", function() { it("adds the reshare to the default, activity and aspects stream", function() {
app.stream = { addNow: $.noop }; app.stream = new app.models.Stream(_, {basePath: "/aspects/all"});
spyOn(app.stream, "addNow"); spyOn(app.stream, "addNow");
var self = this; var self = this;
["/stream", "/activity", "/aspects"].forEach(function(path) { ["/stream", "/activity", "/aspects"].forEach(function(path) {
app.stream.basePath = function() { return path; }; app.stream.basePath = function() { return path; };
self.interactions.reshare(); self.interactions.reshare();
@ -132,10 +134,13 @@ describe("app.models.Post.Interactions", function(){
expect(app.stream.addNow).toHaveBeenCalledWith({id: 1}); expect(app.stream.addNow).toHaveBeenCalledWith({id: 1});
}); });
app.stream = new app.models.Stream(_, {basePath: "/aspects/all"});
}); });
it("doesn't add the reshare to any other stream", function() { it("doesn't add the reshare to any other stream", function() {
app.stream = { addNow: $.noop }; app.stream = new app.models.Stream(_, {basePath: "/aspects/all"});
spyOn(app.stream, "addNow"); spyOn(app.stream, "addNow");
var self = this; var self = this;
["/followed_tags", "/mentions/", "/tag/diaspora", "/people/guid/stream"].forEach(function(path) { ["/followed_tags", "/mentions/", "/tag/diaspora", "/people/guid/stream"].forEach(function(path) {
@ -144,6 +149,8 @@ describe("app.models.Post.Interactions", function(){
jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess); jasmine.Ajax.requests.mostRecent().respondWith(ajaxSuccess);
expect(app.stream.addNow).not.toHaveBeenCalled(); expect(app.stream.addNow).not.toHaveBeenCalled();
}); });
app.stream = new app.models.Stream(_, {basePath: "/aspects/all"});
}); });
it("sets the participation flag for the post", function() { it("sets the participation flag for the post", function() {

View file

@ -1,8 +1,15 @@
describe('app.Router', function () { describe('app.Router', function () {
beforeEach(function() {
delete app.page;
new app.Router().stream();
});
describe('followed_tags', function() { describe('followed_tags', function() {
beforeEach(function() { beforeEach(function() {
loginAs({name: "alice"});
factory.preloads({tagFollowings: []}); factory.preloads({tagFollowings: []});
spec.loadFixture("aspects_index"); spec.loadFixture("aspects_index");
app.publisher = new app.views.Publisher({standalone: true});
}); });
it('decodes name before passing it into TagFollowingAction', function () { it('decodes name before passing it into TagFollowingAction', function () {
@ -74,6 +81,8 @@ describe('app.Router', function () {
describe("aspects", function() { describe("aspects", function() {
it("calls _initializeStreamView", function() { it("calls _initializeStreamView", function() {
new app.models.Stream();
app.publisher = new app.views.Publisher({standalone: true});
spyOn(app.router, "_initializeStreamView"); spyOn(app.router, "_initializeStreamView");
app.router.aspects(); app.router.aspects();
expect(app.router._initializeStreamView).toHaveBeenCalled(); expect(app.router._initializeStreamView).toHaveBeenCalled();
@ -123,6 +132,7 @@ describe('app.Router', function () {
describe("stream", function() { describe("stream", function() {
it("calls _initializeStreamView", function() { it("calls _initializeStreamView", function() {
app.publisher = new app.views.Publisher({standalone: true});
spyOn(app.router, "_initializeStreamView"); spyOn(app.router, "_initializeStreamView");
app.router.stream(); app.router.stream();
expect(app.router._initializeStreamView).toHaveBeenCalled(); expect(app.router._initializeStreamView).toHaveBeenCalled();
@ -169,6 +179,7 @@ describe('app.Router', function () {
app.publisher = { jasmineTestValue: 42 }; app.publisher = { jasmineTestValue: 42 };
app.router._initializeStreamView(); app.router._initializeStreamView();
expect(app.publisher.jasmineTestValue).toEqual(42); expect(app.publisher.jasmineTestValue).toEqual(42);
delete app.publisher; // don't leave fake publisher around
}); });
it("doesn't set app.publisher if there is no publisher element in page", function() { it("doesn't set app.publisher if there is no publisher element in page", function() {

View file

@ -1,11 +1,11 @@
describe("app.views.Comment", function(){ describe("app.views.Comment", function(){
beforeEach(function(){ beforeEach(function() {
this.post = factory.post({author : {diaspora_id : "xxx@xxx.xxx"}}); this.post = factory.post({author : {diaspora_id : "xxx@xxx.xxx"}});
this.comment = factory.comment({parent : this.post.toJSON()}); this.comment = factory.comment({parent : this.post.toJSON()});
this.view = new app.views.Comment({model : this.comment}); this.view = new app.views.Comment({model : this.comment});
}); });
describe("render", function(){ describe("render", function() {
it("has a delete link if the author is the current user", function(){ it("has a delete link if the author is the current user", function(){
loginAs(this.comment.get("author")); loginAs(this.comment.get("author"));
expect(this.view.render().$('.delete').length).toBe(1); expect(this.view.render().$('.delete').length).toBe(1);
@ -47,6 +47,10 @@ describe("app.views.Comment", function(){
}); });
describe("canRemove", function(){ describe("canRemove", function(){
beforeEach(function() {
loginAs({name: "alice"});
});
context("is truthy", function(){ context("is truthy", function(){
it("when ownComment is true", function(){ it("when ownComment is true", function(){
spyOn(this.view, "ownComment").and.returnValue(true); spyOn(this.view, "ownComment").and.returnValue(true);

View file

@ -20,71 +20,6 @@ describe("app.views.Help", function(){
it('should initially show getting help section', function(){ it('should initially show getting help section', function(){
expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_getting_help'); expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_getting_help');
}); });
it('should show account and data management section', function(){
this.view.$el.find('a[data-section=account_and_data_management]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_account_and_data_management')).toBeTruthy();
});
it('should show aspects section', function(){
this.view.$el.find('a[data-section=aspects]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_aspects')).toBeTruthy();
});
it('should show mentions section', function(){
this.view.$el.find('a[data-section=mentions]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_mentions')).toBeTruthy();
});
it('should show pods section', function(){
this.view.$el.find('a[data-section=pods]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_pods')).toBeTruthy();
});
it('should show posts and posting section', function(){
this.view.$el.find('a[data-section=posts_and_posting]').trigger('click');
expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_posts_and_posting');
});
it('should show private posts section', function(){
this.view.$el.find('a[data-section=private_posts]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_private_posts')).toBeTruthy();
});
it('should show public posts section', function(){
this.view.$el.find('a[data-section=public_posts]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_public_posts')).toBeTruthy();
});
it('should show resharing posts section', function(){
this.view.$el.find('a[data-section=resharing_posts]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_resharing_posts')).toBeTruthy();
});
it("should show profile section", function() {
this.view.$el.find("a[data-section=profile]").trigger("click");
expect(this.view.$el.find("#faq").children().first().hasClass("faq_question_profile")).toBeTruthy();
});
it('should show sharing section', function(){
this.view.$el.find('a[data-section=sharing]').trigger('click');
expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_sharing');
});
it('should show tags section', function(){
this.view.$el.find('a[data-section=tags]').trigger('click');
expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_tags');
});
it('should show keyboard shortcuts section', function(){
this.view.$el.find('a[data-section=keyboard_shortcuts]').trigger('click');
expect(this.view.$el.find('#faq').children().first().data('template')).toBe('faq_keyboard_shortcuts');
});
it('should show miscellaneous section', function(){
this.view.$el.find('a[data-section=miscellaneous]').trigger('click');
expect(this.view.$el.find('#faq').children().first().hasClass('faq_question_miscellaneous')).toBeTruthy();
});
}); });
describe("findSection", function() { describe("findSection", function() {

View file

@ -5,6 +5,7 @@ describe("app.views.NotificationDropdown", function() {
this.header = new app.views.Header(); this.header = new app.views.Header();
$("header").prepend(this.header.el); $("header").prepend(this.header.el);
loginAs({guid: "foo"}); loginAs({guid: "foo"});
app.notificationsCollection = new app.collections.Notifications();
this.header.render(); this.header.render();
this.collection = new app.collections.Notifications(); this.collection = new app.collections.Notifications();
this.view = new app.views.NotificationDropdown({el: "#notification-dropdown", collection: this.collection}); this.view = new app.views.NotificationDropdown({el: "#notification-dropdown", collection: this.collection});

View file

@ -25,7 +25,8 @@ describe("app.views.Publisher", function() {
describe("createStatusMessage", function(){ describe("createStatusMessage", function(){
it("doesn't add the status message to the stream", function() { it("doesn't add the status message to the stream", function() {
app.stream = { addNow: $.noop }; app.stream = new app.models.Stream();
spyOn(app.stream, "addNow"); spyOn(app.stream, "addNow");
this.view.createStatusMessage($.Event()); this.view.createStatusMessage($.Event());
jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, responseText: "{\"id\": 1}" }); jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, responseText: "{\"id\": 1}" });
@ -198,7 +199,8 @@ describe("app.views.Publisher", function() {
describe("createStatusMessage", function(){ describe("createStatusMessage", function(){
it("adds the status message to the stream", function() { it("adds the status message to the stream", function() {
app.stream = { addNow: $.noop }; app.stream = new app.models.Stream();
spyOn(app.stream, "addNow"); spyOn(app.stream, "addNow");
this.view.createStatusMessage($.Event()); this.view.createStatusMessage($.Event());
jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, responseText: "{\"id\": 1}" }); jasmine.Ajax.requests.mostRecent().respondWith({ status: 200, responseText: "{\"id\": 1}" });

View file

@ -1,5 +1,6 @@
describe("app.views.SinglePostInteractions", function() { describe("app.views.SinglePostInteractions", function() {
beforeEach(function() { beforeEach(function() {
loginAs({name: "alice", avatar: {small: "http://avatar.com/photo.jpg"}});
this.post = factory.post(); this.post = factory.post();
this.view = new app.views.SinglePostInteractions({model: this.post}); this.view = new app.views.SinglePostInteractions({model: this.post});
}); });

View file

@ -1,6 +1,10 @@
describe("app.views.StreamShortcuts", function () { describe("app.views.StreamShortcuts", function () {
beforeEach(function() { beforeEach(function() {
// This puts `app.page` into the proper state.
delete app.page;
new app.Router().stream();
this.post1 = factory.post({author : factory.author({name : "Rebecca Black", id : 1492})}); this.post1 = factory.post({author : factory.author({name : "Rebecca Black", id : 1492})});
this.post2 = factory.post({author : factory.author({name : "John Stamos", id : 1987})}); this.post2 = factory.post({author : factory.author({name : "John Stamos", id : 1987})});

View file

@ -1,5 +1,9 @@
describe("app.views.StreamPost", function(){ describe("app.views.StreamPost", function(){
beforeEach(function(){ beforeEach(function(){
// This puts `app.page` into the proper state.
delete app.page;
new app.Router().stream();
this.PostViewClass = app.views.StreamPost; this.PostViewClass = app.views.StreamPost;
var posts = $.parseJSON(spec.readFixture("stream_json")); var posts = $.parseJSON(spec.readFixture("stream_json"));

View file

@ -1,5 +1,9 @@
describe("app.views.Stream", function() { describe("app.views.Stream", function() {
beforeEach(function() { beforeEach(function() {
// This puts `app.page` into the proper state.
delete app.page;
new app.Router().stream();
loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}});
this.posts = $.parseJSON(spec.readFixture("stream_json")); this.posts = $.parseJSON(spec.readFixture("stream_json"));

View file

@ -1,5 +1,6 @@
describe("Diaspora.MarkdownEditor", function() { describe("Diaspora.MarkdownEditor", function() {
beforeEach(function() { beforeEach(function() {
Diaspora.I18n.load(spec.defaultLocale, "en");
spec.content().html("<textarea id='fake-textarea'></textarea>"); spec.content().html("<textarea id='fake-textarea'></textarea>");
this.$el = $("#fake-textarea"); this.$el = $("#fake-textarea");
}); });

View file

@ -81,5 +81,4 @@ spec_dir: spec/javascripts
rack_options: rack_options:
Host: '0.0.0.0' Host: '0.0.0.0'
# TODO: refactor tests, they shouldn't fail when they are run in a random order! random: true
random: false