Skip to content

Commit 05f2937

Browse files
authored
Merge pull request #1212 from kennethrioja/registrations-list
[registrations list] frontend and json-ld of registrations in both user and trainer page
2 parents 7531d44 + 6ece894 commit 05f2937

8 files changed

Lines changed: 212 additions & 96 deletions

File tree

app/controllers/trainers_controller.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ def index
2424
# GET /trainers/1.json
2525

2626
def show
27+
@bioschemas = @trainer.user.registrations.flat_map(&:to_bioschemas)
2728
respond_to do |format|
29+
format.html
2830
format.json
2931
format.json_api { render json: @trainer }
30-
format.html
3132
end
3233
end
3334

@@ -45,5 +46,4 @@ def trainer_params
4546
{ :expertise_technical => [] }, { :interest => [] }, { :activity => [] },
4647
{ :fields => [] }, { :social_media => [] })
4748
end
48-
49-
end
49+
end

app/controllers/users_controller.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def invitees
3939
# GET /users/1
4040
# GET /users/1.json
4141
def show
42+
@bioschemas = @user.registrations.flat_map(&:to_bioschemas)
4243
respond_to do |format|
4344
format.html
4445
format.json

app/models/user.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,13 @@ def has_role_in_any_space?(role)
385385
space_roles.where(key: role).any?
386386
end
387387

388+
# Get user's registrations
389+
def registrations
390+
n_events = events.in_current_space
391+
n_materials = materials.in_current_space
392+
n_events + n_materials
393+
end
394+
388395
protected
389396

390397
def reassign_resources(new_owner = User.get_default_user)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<% resource_limit = UsersHelper.user_profile_resource_limit %>
2+
<h3>
3+
List of registrations in <%= TeSS::Config.site['title_short'] %>
4+
</h3>
5+
<div class="my-3">
6+
<% materials = user.materials.in_current_space.limit(resource_limit) %>
7+
<% materials_count = user.materials.in_current_space.count %>
8+
<% upcoming_events = user.events.in_current_space.not_finished %>
9+
<% past_events = user.events.in_current_space.finished %>
10+
<% events = upcoming_events.limit(resource_limit) %>
11+
<% e = user.events.in_current_space.from_verified_users.not_disabled %>
12+
<% events_count = e.count %>
13+
<% not_finished_events_count = e.not_finished.count %>
14+
<% workflows = user.workflows.in_current_space.visible_by(current_user).limit(resource_limit) %>
15+
<% workflows_count = user.workflows.in_current_space.visible_by(current_user).count %>
16+
<% collections = user.collections.in_current_space.visible_by(current_user).limit(resource_limit) %>
17+
<% collections_count = user.collections.in_current_space.visible_by(current_user).count %>
18+
<% activator = tab_activator %>
19+
<% total = materials_count.to_i + events_count.to_i + workflows_count.to_i + collections_count.to_i %>
20+
21+
<!-- Field: registrations -->
22+
<% if total.positive? %>
23+
<p>Added a total of <b><%= total %></b> training resources in <%= TeSS::Config.site['title_short'] %>.</p>
24+
<% end %>
25+
26+
<ul class="nav nav-tabs">
27+
<!-- Tab: Events -->
28+
<% if TeSS::Config.feature['events'] %>
29+
<%= tab('Events', icon_class_for_model('events'), 'events', activator: activator,
30+
disabled: { check: events_count.zero?, message: 'No associated events' },
31+
count: not_finished_events_count.zero? && events_count.positive? ? '0*' : not_finished_events_count) %>
32+
<% end %>
33+
34+
<!-- Tab: Materials -->
35+
<% if TeSS::Config.feature['materials'] %>
36+
<%= tab('Materials', icon_class_for_model('materials'), 'materials', activator: activator,
37+
disabled: { check: materials.none?, message: 'No registered training materials' },
38+
count: materials_count) %>
39+
<% end %>
40+
41+
<!-- Tab: Collections -->
42+
<% if TeSS::Config.feature['collections'] %>
43+
<%= tab('Collections', icon_class_for_model('collections'), 'collections', activator: activator,
44+
disabled: { check: collections.none?, message: 'No registered collections' },
45+
count: collections_count) %>
46+
<% end %>
47+
48+
<!-- Tab: Workflows -->
49+
<% if TeSS::Config.feature['workflows'] %>
50+
<%= tab('Workflows', icon_class_for_model('workflows'), 'workflows', activator: activator,
51+
disabled: { check: workflows.none?, message: 'No workflows' },
52+
count: workflows_count) %>
53+
<% end %>
54+
</ul>
55+
56+
<div class="tab-content">
57+
<!-- Tab: Events -->
58+
<% if TeSS::Config.feature['events'] %>
59+
<%= render partial: 'common/associated_events',
60+
locals: { total_count: upcoming_events.count,
61+
past_count: past_events.count,
62+
limit: resource_limit,
63+
resources: events,
64+
activator: activator,
65+
view_all_link: events_path(user: user.username),
66+
inc_expired_link: events_path(user: user.username, include_expired: true) } %>
67+
<% end %>
68+
69+
<!-- Tab: Materials -->
70+
<% if TeSS::Config.feature['materials'] %>
71+
<%= render partial: 'common/associated_resources',
72+
locals: { model: Material,
73+
total_count: materials_count,
74+
limit: resource_limit,
75+
resources: materials,
76+
activator: activator,
77+
view_all_link: materials_path(user: user.username) } %>
78+
<% end %>
79+
80+
<!-- Tab: Collections -->
81+
<% if TeSS::Config.feature['collections'] %>
82+
<%= render partial: 'common/associated_resources',
83+
locals: { model: Collection,
84+
total_count: collections_count,
85+
limit: resource_limit,
86+
resources: collections,
87+
activator: activator,
88+
view_all_link: collections_path(user: user.username) } %>
89+
<% end %>
90+
91+
<!-- Tab: Workflows -->
92+
<% if TeSS::Config.feature['workflows'] %>
93+
<%= render partial: 'common/associated_resources',
94+
locals: { model: Workflow,
95+
total_count: workflows_count,
96+
limit: resource_limit,
97+
resources: workflows,
98+
activator: activator,
99+
view_all_link: workflows_path(user: user.username) } %>
100+
<% end %>
101+
</div> <!-- end tab-content -->
102+
</div>

app/views/trainers/show.html.erb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,8 @@
4848
<!-- Other metadata -->
4949
<%= render partial: 'trainers/partials/twitter_card', locals: { trainer: @trainer } %>
5050
</div>
51+
52+
<!-- Field: registrations list with Events, Materials, Collections, Workflows -->
53+
<%= render(partial: 'common/registrations_list', locals: { user: @trainer.user }) %>
5154
</div>
5255
</div>

app/views/users/show.html.erb

Lines changed: 2 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
<% resource_limit = UsersHelper.user_profile_resource_limit %>
21
<div class="wrapper collapsing-wrapper-tb">
32
<%- model_class = Profile -%>
43

@@ -128,97 +127,7 @@
128127

129128
<%= render(partial: 'users/partials/ban', locals: { ban: @user.ban }) if @user.banned? && current_user.try(:is_admin?) %>
130129

131-
<div class="my-3">
132-
<% materials = @user.materials.in_current_space.limit(resource_limit) %>
133-
<% materials_count = @user.materials.in_current_space.count %>
134-
<% upcoming_events = @user.events.in_current_space.not_finished %>
135-
<% past_events = @user.events.in_current_space.finished %>
136-
<% events = upcoming_events.limit(resource_limit) %>
137-
<% e = @user.events.in_current_space.from_verified_users.not_disabled %>
138-
<% events_count = e.count %>
139-
<% not_finished_events_count = e.not_finished.count %>
140-
<% workflows = @user.workflows.in_current_space.visible_by(current_user).limit(resource_limit) %>
141-
<% workflows_count = @user.workflows.in_current_space.visible_by(current_user).count %>
142-
<% collections = @user.collections.in_current_space.visible_by(current_user).limit(resource_limit) %>
143-
<% collections_count = @user.collections.in_current_space.visible_by(current_user).count %>
144-
<% activator = tab_activator %>
145-
146-
<ul class="nav nav-tabs">
147-
<!-- Tab: Events -->
148-
<% if feature_enabled?('events') %>
149-
<%= tab('Events', icon_class_for_model('events'), 'events', activator: activator,
150-
disabled: { check: events_count.zero?, message: 'No associated events' },
151-
count: not_finished_events_count.zero? && events_count.positive? ? '0*' : not_finished_events_count) %>
152-
<% end %>
153-
154-
<!-- Tab: Materials -->
155-
<% if feature_enabled?('materials') %>
156-
<%= tab('Materials', icon_class_for_model('materials'), 'materials', activator: activator,
157-
disabled: { check: materials.none?, message: 'No registered training materials' },
158-
count: materials_count) %>
159-
<% end %>
160-
161-
<!-- Tab: Collections -->
162-
<% if feature_enabled?('collections') %>
163-
<%= tab('Collections', icon_class_for_model('collections'), 'collections', activator: activator,
164-
disabled: { check: collections.none?, message: 'No registered collections' },
165-
count: collections_count) %>
166-
<% end %>
167-
168-
<!-- Tab: Workflows -->
169-
<% if feature_enabled?('workflows') %>
170-
<%= tab('Workflows', icon_class_for_model('workflows'), 'workflows', activator: activator,
171-
disabled: { check: workflows.none?, message: 'No workflows' },
172-
count: workflows_count) %>
173-
<% end %>
174-
</ul>
175-
176-
<div class="tab-content">
177-
<!-- Tab: Events -->
178-
<% if feature_enabled?('events') %>
179-
<%= render partial: 'common/associated_events',
180-
locals: { total_count: upcoming_events.count,
181-
past_count: past_events.count,
182-
limit: resource_limit,
183-
resources: events,
184-
activator: activator,
185-
view_all_link: events_path(user: @user.username),
186-
inc_expired_link: events_path(user: @user.username, include_expired: true) } %>
187-
<% end %>
188-
189-
<!-- Tab: Materials -->
190-
<% if feature_enabled?('materials') %>
191-
<%= render partial: 'common/associated_resources',
192-
locals: { model: Material,
193-
total_count: materials_count,
194-
limit: resource_limit,
195-
resources: materials,
196-
activator: activator,
197-
view_all_link: materials_path(user: @user.username) } %>
198-
<% end %>
199-
200-
<!-- Tab: Collections -->
201-
<% if feature_enabled?('collections') %>
202-
<%= render partial: 'common/associated_resources',
203-
locals: { model: Collection,
204-
total_count: collections_count,
205-
limit: resource_limit,
206-
resources: collections,
207-
activator: activator,
208-
view_all_link: collections_path(user: @user.username) } %>
209-
<% end %>
210-
211-
<!-- Tab: Workflows -->
212-
<% if feature_enabled?('workflows') %>
213-
<%= render partial: 'common/associated_resources',
214-
locals: { model: Workflow,
215-
total_count: workflows_count,
216-
limit: resource_limit,
217-
resources: workflows,
218-
activator: activator,
219-
view_all_link: workflows_path(user: @user.username) } %>
220-
<% end %>
221-
</div> <!-- end tab-content -->
222-
</div>
130+
<!-- Registrations list: Events, Materials, Collections, Workflows -->
131+
<%= render(partial: 'common/registrations_list', locals: { user: @user }) %>
223132
</div>
224133
</div>

test/controllers/trainers_controller_test.rb

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
class TrainersControllerTest < ActionController::TestCase
44
include Devise::Test::ControllerHelpers
55

6+
setup do
7+
@user = users(:trainer_user)
8+
@trainer = @user.profile
9+
end
10+
611
test 'get all trainers' do
712
get :index
813
assert_response :success
@@ -12,4 +17,48 @@ class TrainersControllerTest < ActionController::TestCase
1217
assert_includes trainers, users(:trainer_user).profile
1318
end
1419

20+
test 'should show material and event in trainer page as bioschemas JSON-LD' do
21+
material = materials(:good_material)
22+
material.user_id = @user.id
23+
material.scientific_topic_uris = ['http://edamontology.org/topic_0654']
24+
material.save!
25+
26+
event = events(:one)
27+
event.user = @user
28+
event.scientific_topic_uris = ['http://edamontology.org/topic_0654']
29+
event.save!
30+
31+
get :show, params: { id: @trainer, format: :html }
32+
assert_response :success
33+
assert assigns(:trainer)
34+
35+
doc = Nokogiri::HTML(response.body)
36+
jsonld = doc
37+
.css('script[type="application/ld+json"]')
38+
.map do |s|
39+
JSON.parse(s.text)
40+
rescue JSON::ParserError
41+
nil
42+
end
43+
.compact
44+
45+
json_material = jsonld.find { |entry| entry['name'] == material.title }
46+
assert_equal material.title, json_material['name']
47+
assert_equal 'http://schema.org', json_material['@context']
48+
assert_equal 'LearningResource', json_material['@type']
49+
assert_equal 'https://bioschemas.org/profiles/TrainingMaterial/1.0-RELEASE', json_material['dct:conformsTo']['@id']
50+
assert_equal material.url, json_material['url']
51+
assert_equal material.scientific_topic_uris.first, json_material['about'].first['@id']
52+
53+
json_event = jsonld.find { |entry| entry['name'] == event.title }
54+
assert_equal 'http://schema.org', json_event['@context']
55+
assert_equal 'Course', json_event['@type']
56+
assert_equal 'https://bioschemas.org/profiles/Course/1.0-RELEASE', json_event['dct:conformsTo']['@id']
57+
assert_equal event.title, json_event['name']
58+
assert_equal event.url, json_event['url']
59+
assert_equal event.scientific_topic_uris.first, json_event['about'].first['@id']
60+
external_resource = event.external_resources.first
61+
assert_not_nil external_resource
62+
assert_equal external_resource.url, json_event['mentions'].first['url']
63+
end
1564
end

test/controllers/users_controller_test.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,4 +525,49 @@ class UsersControllerTest < ActionController::TestCase
525525
assert_response :success
526526
assert_select '#sidebar button', text: 'Authenticate your ORCID', count: 0
527527
end
528+
529+
test 'should show material and event in trainer page as bioschemas JSON-LD' do
530+
material = materials(:good_material)
531+
material.user_id = @user.id
532+
material.scientific_topic_uris = ['http://edamontology.org/topic_0654']
533+
material.save!
534+
535+
event = events(:one)
536+
event.user = @user
537+
event.scientific_topic_uris = ['http://edamontology.org/topic_0654']
538+
event.save!
539+
540+
get :show, params: { id: @user, format: :html }
541+
assert_response :success
542+
assert assigns(:user)
543+
544+
doc = Nokogiri::HTML(response.body)
545+
jsonld = doc
546+
.css('script[type="application/ld+json"]')
547+
.map do |s|
548+
JSON.parse(s.text)
549+
rescue JSON::ParserError
550+
nil
551+
end
552+
.compact
553+
554+
json_material = jsonld.find { |entry| entry['name'] == material.title }
555+
assert_equal material.title, json_material['name']
556+
assert_equal 'http://schema.org', json_material['@context']
557+
assert_equal 'LearningResource', json_material['@type']
558+
assert_equal 'https://bioschemas.org/profiles/TrainingMaterial/1.0-RELEASE', json_material['dct:conformsTo']['@id']
559+
assert_equal material.url, json_material['url']
560+
assert_equal material.scientific_topic_uris.first, json_material['about'].first['@id']
561+
562+
json_event = jsonld.find { |entry| entry['name'] == event.title }
563+
assert_equal 'http://schema.org', json_event['@context']
564+
assert_equal 'Course', json_event['@type']
565+
assert_equal 'https://bioschemas.org/profiles/Course/1.0-RELEASE', json_event['dct:conformsTo']['@id']
566+
assert_equal event.title, json_event['name']
567+
assert_equal event.url, json_event['url']
568+
assert_equal event.scientific_topic_uris.first, json_event['about'].first['@id']
569+
external_resource = event.external_resources.first
570+
assert_not_nil external_resource
571+
assert_equal external_resource.url, json_event['mentions'].first['url']
572+
end
528573
end

0 commit comments

Comments
 (0)