mirror of
https://github.com/discourse/discourse-solved.git
synced 2026-09-16 22:52:12 -04:00
Merge branch 'main' into dev/post-quoted-content-component
This commit is contained in:
+1
-1
@@ -35,7 +35,7 @@ GEM
|
||||
prettier_print (1.2.1)
|
||||
prism (1.4.0)
|
||||
racc (1.8.1)
|
||||
rack (3.1.15)
|
||||
rack (3.1.16)
|
||||
rainbow (3.1.1)
|
||||
regexp_parser (2.10.0)
|
||||
rubocop (1.75.8)
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"tests": {
|
||||
"requiredPlugins": [
|
||||
"https://github.com/discourse/discourse-assign"
|
||||
"discourse-assign"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DiscourseSolved::SolvedTopicsController < ::ApplicationController
|
||||
requires_plugin DiscourseSolved::PLUGIN_NAME
|
||||
|
||||
def by_user
|
||||
params.require(:username)
|
||||
user =
|
||||
fetch_user_from_params(
|
||||
include_inactive:
|
||||
current_user.try(:staff?) || (current_user && SiteSetting.show_inactive_accounts),
|
||||
)
|
||||
raise Discourse::NotFound unless guardian.public_can_see_profiles?
|
||||
raise Discourse::NotFound unless guardian.can_see_profile?(user)
|
||||
|
||||
offset = [0, params[:offset].to_i].max
|
||||
limit = params.fetch(:limit, 30).to_i
|
||||
|
||||
posts =
|
||||
Post
|
||||
.joins(
|
||||
"INNER JOIN discourse_solved_solved_topics ON discourse_solved_solved_topics.answer_post_id = posts.id",
|
||||
)
|
||||
.joins(:topic)
|
||||
.joins("LEFT JOIN categories ON categories.id = topics.category_id")
|
||||
.where(user_id: user.id, deleted_at: nil)
|
||||
.where(topics: { archetype: Archetype.default, deleted_at: nil })
|
||||
.where(
|
||||
"topics.category_id IS NULL OR NOT categories.read_restricted OR topics.category_id IN (:secure_category_ids)",
|
||||
secure_category_ids: guardian.secure_category_ids,
|
||||
)
|
||||
.includes(:user, topic: %i[category tags])
|
||||
.order("discourse_solved_solved_topics.created_at DESC")
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
|
||||
render_serialized(posts, DiscourseSolved::SolvedPostSerializer, root: "user_solved_posts")
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class DiscourseSolved::SolvedPostSerializer < ApplicationSerializer
|
||||
attributes :created_at,
|
||||
:archived,
|
||||
:avatar_template,
|
||||
:category_id,
|
||||
:closed,
|
||||
:cooked,
|
||||
:excerpt,
|
||||
:name,
|
||||
:post_id,
|
||||
:post_number,
|
||||
:post_type,
|
||||
:raw,
|
||||
:slug,
|
||||
:topic_id,
|
||||
:topic_title,
|
||||
:truncated,
|
||||
:url,
|
||||
:user_id,
|
||||
:username
|
||||
|
||||
def archived
|
||||
object.topic.archived
|
||||
end
|
||||
|
||||
def avatar_template
|
||||
object.user&.avatar_template
|
||||
end
|
||||
|
||||
def category_id
|
||||
object.topic.category_id
|
||||
end
|
||||
|
||||
def closed
|
||||
object.topic.closed
|
||||
end
|
||||
|
||||
def excerpt
|
||||
@excerpt ||= PrettyText.excerpt(cooked, 300, keep_emoji_images: true)
|
||||
end
|
||||
|
||||
def name
|
||||
object.user&.name
|
||||
end
|
||||
|
||||
def include_name?
|
||||
SiteSetting.enable_names?
|
||||
end
|
||||
|
||||
def post_id
|
||||
object.id
|
||||
end
|
||||
|
||||
def slug
|
||||
Slug.for(object.topic.title)
|
||||
end
|
||||
|
||||
def include_slug?
|
||||
object.topic.title.present?
|
||||
end
|
||||
|
||||
def topic_title
|
||||
object.topic.title
|
||||
end
|
||||
|
||||
def truncated
|
||||
true
|
||||
end
|
||||
|
||||
def include_truncated?
|
||||
cooked.length > 300
|
||||
end
|
||||
|
||||
def url
|
||||
"#{Discourse.base_url}#{object.url}"
|
||||
end
|
||||
|
||||
def user_id
|
||||
object.user_id
|
||||
end
|
||||
|
||||
def username
|
||||
object.user&.username
|
||||
end
|
||||
end
|
||||
@@ -1,15 +1,110 @@
|
||||
import UserActivityStreamRoute from "discourse/routes/user-activity-stream";
|
||||
import { tracked } from "@glimmer/tracking";
|
||||
import EmberObject from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { Promise } from "rsvp";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import DiscourseRoute from "discourse/routes/discourse";
|
||||
import { i18n } from "discourse-i18n";
|
||||
|
||||
export default class UserActivitySolved extends UserActivityStreamRoute {
|
||||
userActionType = 15;
|
||||
noContentHelpKey = "solved.no_solutions";
|
||||
class SolvedPostsStream {
|
||||
@tracked content = [];
|
||||
@tracked loading = false;
|
||||
@tracked loaded = false;
|
||||
@tracked itemsLoaded = 0;
|
||||
@tracked canLoadMore = true;
|
||||
|
||||
constructor({ username, siteCategories }) {
|
||||
this.username = username;
|
||||
this.siteCategories = siteCategories;
|
||||
}
|
||||
|
||||
get noContent() {
|
||||
return this.loaded && this.content.length === 0;
|
||||
}
|
||||
|
||||
findItems() {
|
||||
if (this.loading || !this.canLoadMore) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
|
||||
const limit = 20;
|
||||
return ajax(
|
||||
`/solution/by_user.json?username=${this.username}&offset=${this.itemsLoaded}&limit=${limit}`
|
||||
)
|
||||
.then((result) => {
|
||||
const userSolvedPosts = result.user_solved_posts || [];
|
||||
|
||||
if (userSolvedPosts.length === 0) {
|
||||
this.canLoadMore = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const posts = userSolvedPosts.map((p) => {
|
||||
const post = EmberObject.create(p);
|
||||
post.set("titleHtml", post.topic_title);
|
||||
post.set("postUrl", post.url);
|
||||
|
||||
if (post.category_id && this.siteCategories) {
|
||||
post.set(
|
||||
"category",
|
||||
this.siteCategories.find((c) => c.id === post.category_id)
|
||||
);
|
||||
}
|
||||
return post;
|
||||
});
|
||||
|
||||
this.content = [...this.content, ...posts];
|
||||
this.itemsLoaded = this.itemsLoaded + userSolvedPosts.length;
|
||||
|
||||
if (userSolvedPosts.length < limit) {
|
||||
this.canLoadMore = false;
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.loaded = true;
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default class UserActivitySolved extends DiscourseRoute {
|
||||
@service site;
|
||||
@service currentUser;
|
||||
|
||||
model() {
|
||||
const user = this.modelFor("user");
|
||||
|
||||
const stream = new SolvedPostsStream({
|
||||
username: user.username,
|
||||
siteCategories: this.site.categories,
|
||||
});
|
||||
|
||||
return stream.findItems().then(() => {
|
||||
return {
|
||||
stream,
|
||||
emptyState: this.emptyState(),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
setupController(controller, model) {
|
||||
controller.setProperties({
|
||||
model,
|
||||
emptyState: this.emptyState(),
|
||||
});
|
||||
}
|
||||
|
||||
renderTemplate() {
|
||||
this.render("user-activity-solved");
|
||||
}
|
||||
|
||||
emptyState() {
|
||||
const user = this.modelFor("user");
|
||||
|
||||
let title, body;
|
||||
if (this.isCurrentUser(user)) {
|
||||
if (this.currentUser && user.id === this.currentUser.id) {
|
||||
title = i18n("solved.no_solved_topics_title");
|
||||
body = i18n("solved.no_solved_topics_body");
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import RouteTemplate from "ember-route-template";
|
||||
import EmptyState from "discourse/components/empty-state";
|
||||
import UserStream from "discourse/components/user-stream";
|
||||
|
||||
export default RouteTemplate(
|
||||
<template>
|
||||
{{#if @controller.model.stream.noContent}}
|
||||
<EmptyState
|
||||
@title={{@controller.model.emptyState.title}}
|
||||
@body={{@controller.model.emptyState.body}}
|
||||
/>
|
||||
{{else}}
|
||||
<UserStream @stream={{@controller.model.stream}} />
|
||||
{{/if}}
|
||||
</template>
|
||||
);
|
||||
@@ -10,6 +10,7 @@ el:
|
||||
alt:
|
||||
solved:
|
||||
accepted_notification: "αποδεκτό"
|
||||
solutions: "Λύσεις"
|
||||
solved:
|
||||
title: "Λύθηκε"
|
||||
allow_accepted_answers: "Επιτρέψτε στον κάτοχο και το προσωπικό να επισημάνει μια απάντηση ως λύση"
|
||||
@@ -29,6 +30,13 @@ el:
|
||||
all: "όλα"
|
||||
solved: "λύθηκε"
|
||||
unsolved: "άλυτο"
|
||||
no_solved_topics_title: "Δεν έχετε λύσει κανένα θέμα ακόμα"
|
||||
no_solved_topics_title_others: "Ο χρήστης %{username} δεν έχει λύσει κανένα θέμα ακόμα"
|
||||
no_answer:
|
||||
title: Έχει απαντηθεί η ερώτηση σας;
|
||||
description: "Επισημάνετε την απάντηση και βοηθήστε άλλους χρησιμοποιώντας το κουμπί λύσης κάτω από τη σωστή απάντηση."
|
||||
notification:
|
||||
title: "η ανάρτηση σας επισημάνθηκε ως λύση"
|
||||
topic_statuses:
|
||||
solved:
|
||||
help: "Αυτό το θέμα έχει μια λύση"
|
||||
@@ -36,13 +44,21 @@ el:
|
||||
advanced:
|
||||
statuses:
|
||||
solved: "έχουν επιλυθεί"
|
||||
unsolved: "δεν έχουν επιλυθεί"
|
||||
admin:
|
||||
web_hooks:
|
||||
solved_event:
|
||||
group_name: "Επιλύθηκε γεγονός"
|
||||
api:
|
||||
scopes:
|
||||
descriptions:
|
||||
solved:
|
||||
answer: Αποδοχή/Απόρριψη μίας λύσης.
|
||||
discourse_automation:
|
||||
triggerables:
|
||||
first_accepted_solution:
|
||||
max_trust_level:
|
||||
any: Οποιοδήποτε
|
||||
fields:
|
||||
maximum_trust_level:
|
||||
label: Επίπεδο Εμπιστοσύνης
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# https://translate.discourse.org/
|
||||
|
||||
el:
|
||||
accepted_answer: "Αποδεκτή Απάντηση"
|
||||
site_settings:
|
||||
solved_enabled: "Ενεργοποιήστε το πρόσθετο solved, επιτρέψτε στους χρήστες να επιλέγουν λύσεις για θέματα"
|
||||
accept_all_solutions_trust_level: "Απαιτείται ελάχιστο επίπεδο εμπιστοσύνης για αποδοχή λύσεων σε οποιοδήποτε θέμα (ακόμα και όταν δεν είναι OP)"
|
||||
@@ -23,3 +24,7 @@ el:
|
||||
badges:
|
||||
solved_1:
|
||||
name: "Λύθηκε!"
|
||||
discourse_automation:
|
||||
triggerables:
|
||||
first_accepted_solution:
|
||||
title: Πρώτη αποδεκτή λύση
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
DiscourseSolved::Engine.routes.draw do
|
||||
post "/accept" => "answer#accept"
|
||||
post "/unaccept" => "answer#unaccept"
|
||||
|
||||
get "/by_user" => "solved_topics#by_user"
|
||||
end
|
||||
|
||||
Discourse::Application.routes.draw { mount ::DiscourseSolved::Engine, at: "solution" }
|
||||
|
||||
@@ -5,15 +5,15 @@ module DiscourseSolved
|
||||
def self.check(post, trust_level:)
|
||||
return false if post.archetype != Archetype.default
|
||||
return false if !post&.user&.human?
|
||||
return true if trust_level == "any"
|
||||
|
||||
return false if TrustLevel.compare(post&.user&.trust_level, trust_level.to_i)
|
||||
|
||||
if !UserAction.where(user_id: post&.user_id, action_type: UserAction::SOLVED).exists?
|
||||
return true
|
||||
if trust_level != "any" && TrustLevel.compare(post&.user&.trust_level, trust_level.to_i)
|
||||
return false
|
||||
end
|
||||
|
||||
false
|
||||
!DiscourseSolved::SolvedTopic
|
||||
.joins(:answer_post)
|
||||
.where("posts.user_id = ? AND posts.id != ?", post.user_id, post.id)
|
||||
.exists?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,56 +1,43 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rails_helper"
|
||||
|
||||
describe DiscourseSolved::FirstAcceptedPostSolutionValidator do
|
||||
fab!(:user_tl1) { Fabricate(:user, trust_level: TrustLevel[1], refresh_auto_groups: true) }
|
||||
|
||||
context "when user is under max trust level" do
|
||||
context "with no post accepted yet" do
|
||||
it "validates the post" do
|
||||
post_1 = create_post(user: user_tl1)
|
||||
expect(described_class.check(post_1, trust_level: TrustLevel[2])).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
context "with already had accepted posts" do
|
||||
before do
|
||||
accepted_post = create_post(user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(accepted_post, Discourse.system_user)
|
||||
end
|
||||
|
||||
it "doesn’t validate the post" do
|
||||
post_1 = create_post(user: user_tl1)
|
||||
expect(described_class.check(post_1, trust_level: TrustLevel[2])).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when a user is above or equal max trust level" do
|
||||
context "with no post accepted yet" do
|
||||
it "doesn’t validate the post" do
|
||||
post_1 = create_post(user: user_tl1)
|
||||
expect(described_class.check(post_1, trust_level: TrustLevel[1])).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "when a post is already accepted" do
|
||||
before do
|
||||
accepted_post = create_post(user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(accepted_post, Discourse.system_user)
|
||||
end
|
||||
|
||||
it "doesn’t validate the post" do
|
||||
post_1 = create_post(user: user_tl1)
|
||||
expect(described_class.check(post_1, trust_level: TrustLevel[1])).to eq(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when using any trust level" do
|
||||
context "when trust level is 'any'" do
|
||||
it "validates the post" do
|
||||
post_1 = create_post(user: user_tl1)
|
||||
expect(described_class.check(post_1, trust_level: "any")).to eq(true)
|
||||
post = Fabricate(:post, user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(post, Discourse.system_user)
|
||||
|
||||
expect(described_class.check(post, trust_level: "any")).to eq(true)
|
||||
end
|
||||
|
||||
it "invalidates if post user already has an accepted post" do
|
||||
previously_accepted_post = Fabricate(:post, user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(previously_accepted_post, Discourse.system_user)
|
||||
|
||||
newly_accepted_post = Fabricate(:post, user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(newly_accepted_post, Discourse.system_user)
|
||||
|
||||
expect(described_class.check(newly_accepted_post, trust_level: "any")).to eq(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "with specified trust level that is not 'any'" do
|
||||
# the automation indicates "users under this Trust Level will trigger this automation"
|
||||
|
||||
it "invalidates if the user is higher than or equal to the specified trust level" do
|
||||
post = Fabricate(:post, user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(post, Discourse.system_user)
|
||||
|
||||
expect(described_class.check(post, trust_level: TrustLevel[0])).to eq(false)
|
||||
expect(described_class.check(post, trust_level: TrustLevel[1])).to eq(false)
|
||||
end
|
||||
|
||||
it "validates the post when user is under specified trust level" do
|
||||
post = Fabricate(:post, user: user_tl1)
|
||||
DiscourseSolved.accept_answer!(post, Discourse.system_user)
|
||||
|
||||
expect(described_class.check(post, trust_level: TrustLevel[2])).to eq(true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe DiscourseSolved::SolvedTopicsController do
|
||||
fab!(:user)
|
||||
fab!(:another_user) { Fabricate(:user) }
|
||||
fab!(:admin)
|
||||
fab!(:topic)
|
||||
fab!(:post) { Fabricate(:post, topic:) }
|
||||
fab!(:answer_post) { Fabricate(:post, topic:, user:) }
|
||||
fab!(:solved_topic) { Fabricate(:solved_topic, topic:, answer_post:) }
|
||||
|
||||
describe "#by_user" do
|
||||
context "when accessing with username" do
|
||||
it "returns solved posts for the specified user" do
|
||||
sign_in(admin)
|
||||
|
||||
get "/solution/by_user.json", params: { username: user.username }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result["user_solved_posts"]).to be_present
|
||||
expect(result["user_solved_posts"].length).to eq(1)
|
||||
expect(result["user_solved_posts"][0]["post_id"]).to eq(answer_post.id)
|
||||
end
|
||||
|
||||
it "returns 404 for a non-existent user" do
|
||||
sign_in(admin)
|
||||
|
||||
get "/solution/by_user.json", params: { username: "non-existent-user" }
|
||||
|
||||
expect(response.status).to eq(404)
|
||||
end
|
||||
|
||||
it "correctly handles the offset parameter" do
|
||||
sign_in(admin)
|
||||
|
||||
get "/solution/by_user.json", params: { username: user.username, offset: 1 }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result["user_solved_posts"]).to be_empty
|
||||
end
|
||||
|
||||
it "correctly handles the limit parameter" do
|
||||
Fabricate(:solved_topic, answer_post: Fabricate(:post, user:))
|
||||
|
||||
sign_in(admin)
|
||||
|
||||
get "/solution/by_user.json", params: { username: user.username, limit: 1 }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result["user_solved_posts"].length).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
context "when accessing without username" do
|
||||
it "returns 400 for the current user" do
|
||||
sign_in(user)
|
||||
|
||||
get "/solution/by_user.json"
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
|
||||
it "returns 400 if not logged in" do
|
||||
get "/solution/by_user.json"
|
||||
|
||||
expect(response.status).to eq(400)
|
||||
end
|
||||
end
|
||||
|
||||
context "with visibility restrictions" do
|
||||
context "with private category solved topic" do
|
||||
fab!(:group) { Fabricate(:group).tap { |g| g.add(user) } }
|
||||
fab!(:private_category) { Fabricate(:private_category, group:) }
|
||||
fab!(:private_topic) { Fabricate(:topic, category: private_category) }
|
||||
fab!(:private_post) { Fabricate(:post, topic: private_topic) }
|
||||
fab!(:private_answer_post) { Fabricate(:post, topic: private_topic, user: user) }
|
||||
fab!(:private_solved_topic) do
|
||||
Fabricate(:solved_topic, topic: private_topic, answer_post: private_answer_post)
|
||||
end
|
||||
|
||||
it "respects category permissions" do
|
||||
sign_in(another_user)
|
||||
|
||||
get "/solution/by_user.json", params: { username: user.username }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
# admin sees both solutions
|
||||
expect(result["user_solved_posts"].length).to eq(1)
|
||||
|
||||
sign_in(user)
|
||||
|
||||
get "/solution/by_user.json", params: { username: user.username }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result["user_solved_posts"].length).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not return PMs" do
|
||||
topic.update(archetype: Archetype.private_message, category: nil)
|
||||
|
||||
sign_in(user)
|
||||
|
||||
get "/solution/by_user.json", params: { username: user.username }
|
||||
|
||||
expect(response.status).to eq(200)
|
||||
result = response.parsed_body
|
||||
expect(result["user_solved_posts"]).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,10 +1,10 @@
|
||||
# frozen_string_literal: true
|
||||
describe "About page", type: :system do
|
||||
describe "Solved", type: :system do
|
||||
fab!(:admin)
|
||||
fab!(:solver) { Fabricate(:user) }
|
||||
fab!(:accepter) { Fabricate(:user) }
|
||||
fab!(:topic) { Fabricate(:post, user: admin).topic }
|
||||
fab!(:post1) { Fabricate(:post, topic:, user: solver, cooked: "The answer is 42") }
|
||||
fab!(:solver_post) { Fabricate(:post, topic:, user: solver, cooked: "The answer is 42") }
|
||||
let(:topic_page) { PageObjects::Pages::Topic.new }
|
||||
|
||||
before do
|
||||
@@ -62,4 +62,13 @@ describe "About page", type: :system do
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "shows the solved post in user activity at /my/activity/solved" do
|
||||
Fabricate(:solved_topic, topic:, answer_post: solver_post, accepter:)
|
||||
|
||||
sign_in(solver)
|
||||
visit "/my/activity/solved"
|
||||
|
||||
expect(page.find(".post-list")).to have_content(solver_post.cooked)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,8 +9,8 @@ acceptance(
|
||||
needs.user();
|
||||
|
||||
needs.pretender((server, helper) => {
|
||||
server.get("/user_actions.json", () =>
|
||||
helper.response({ user_actions: [] })
|
||||
server.get("/solution/by_user.json", () =>
|
||||
helper.response({ user_solved_posts: [] })
|
||||
);
|
||||
});
|
||||
|
||||
@@ -18,22 +18,22 @@ acceptance(
|
||||
await visit(`/u/eviltrout/activity/solved`);
|
||||
|
||||
assert
|
||||
.dom("div.empty-state span.empty-state-title")
|
||||
.dom(".empty-state .empty-state__title")
|
||||
.hasText(i18n("solved.no_solved_topics_title"));
|
||||
assert
|
||||
.dom("div.empty-state div.empty-state-body")
|
||||
.dom(".empty-state .empty-state__body")
|
||||
.hasText(i18n("solved.no_solved_topics_body"));
|
||||
});
|
||||
|
||||
test("When looking at another user's activity", async function (assert) {
|
||||
await visit(`/u/charlie/activity/solved`);
|
||||
|
||||
assert.dom("div.empty-state span.empty-state-title").hasText(
|
||||
assert.dom(".empty-state .empty-state__title").hasText(
|
||||
i18n("solved.no_solved_topics_title_others", {
|
||||
username: "charlie",
|
||||
})
|
||||
);
|
||||
assert.dom("div.empty-state div.empty-state-body").hasNoText();
|
||||
assert.dom(".empty-state .empty-state__body").doesNotExist();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user