foreman_rh_cloud 12.2.15 → 12.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/models/concerns/rh_cloud_host.rb +31 -1
- data/lib/foreman_inventory_upload/async/create_missing_insights_facets.rb +8 -2
- data/lib/foreman_rh_cloud/plugin.rb +1 -1
- data/lib/foreman_rh_cloud/version.rb +1 -1
- data/package.json +1 -1
- data/test/unit/rh_cloud_host_test.rb +154 -0
- data/webpack/InsightsHostDetailsTab/NewHostDetailsTab.js +18 -3
- data/webpack/InsightsHostDetailsTab/__tests__/NewHostDetailsTab.test.js +154 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0df237afaaed946309bf58184191f10cc41adad7ad746077f7445a26d880e24f
|
|
4
|
+
data.tar.gz: 302e496860920fc29db9807621fd8ceb442d08af831184ee8dd743963e153b50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20278c38dcedc487a60321c837bbdb4bfe20f3db46873a7482ab43922c91b9d8c4b1529a2d4e024bf24ba5c2197163832e323bb4a4da26a4c2cb14cb2ad492b7
|
|
7
|
+
data.tar.gz: 78c2f26bf97d4f70fe7f72ef3e8fd1d2c297bac241da5e43cefbb23f221eb2e934179937dd858f695be4bcc5761fbf869b4e48e71bde607e94541df38e93e496
|
|
@@ -21,7 +21,8 @@ module RhCloudHost
|
|
|
21
21
|
scoped_search :relation => :inventory_sync_status_object, :on => :status, :rename => :insights_inventory_sync_status,
|
|
22
22
|
:complete_value => { :disconnect => ::InventorySync::InventoryStatus::DISCONNECT,
|
|
23
23
|
:sync => ::InventorySync::InventoryStatus::SYNC }
|
|
24
|
-
scoped_search :
|
|
24
|
+
scoped_search :on => :id, :rename => :insights_uuid, :only_explicit => true,
|
|
25
|
+
:ext_method => :search_by_insights_uuid, :complete_value => false
|
|
25
26
|
|
|
26
27
|
def insights_facet
|
|
27
28
|
insights
|
|
@@ -41,4 +42,33 @@ module RhCloudHost
|
|
|
41
42
|
insights_facet.update!(uuid: subscription_facet.uuid)
|
|
42
43
|
end
|
|
43
44
|
end
|
|
45
|
+
|
|
46
|
+
module ClassMethods
|
|
47
|
+
def search_by_insights_uuid(_key, operator, value)
|
|
48
|
+
# Determine which facet table to search based on IoP mode
|
|
49
|
+
facet_table = ForemanRhCloud.with_iop_smart_proxy? ? Katello::Host::SubscriptionFacet.table_name : InsightsFacet.table_name
|
|
50
|
+
|
|
51
|
+
# Build SQL condition
|
|
52
|
+
if ['IN', 'NOT IN'].include?(operator)
|
|
53
|
+
# For IN/NOT IN, value may be an array or comma-separated string
|
|
54
|
+
# Convert to array and build placeholders for each value
|
|
55
|
+
values = value.is_a?(Array) ? value : value.to_s.split(',').map(&:strip)
|
|
56
|
+
placeholders = (['?'] * values.size).join(',')
|
|
57
|
+
condition = sanitize_sql_for_conditions(
|
|
58
|
+
["#{facet_table}.uuid #{operator} (#{placeholders})", *values]
|
|
59
|
+
)
|
|
60
|
+
else
|
|
61
|
+
# For other operators (=, !=, LIKE, etc.), use value_to_sql for proper SQL formatting
|
|
62
|
+
condition = sanitize_sql_for_conditions(
|
|
63
|
+
["#{facet_table}.uuid #{operator} ?", value_to_sql(operator, value)]
|
|
64
|
+
)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Return search parameters with LEFT JOIN to include hosts without facets
|
|
68
|
+
{
|
|
69
|
+
joins: "LEFT JOIN #{facet_table} ON #{facet_table}.host_id = #{Host::Managed.table_name}.id",
|
|
70
|
+
conditions: condition,
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
end
|
|
44
74
|
end
|
|
@@ -7,9 +7,15 @@ module ForemanInventoryUpload
|
|
|
7
7
|
|
|
8
8
|
def run
|
|
9
9
|
organization = ::Organization.find(input[:organization_id])
|
|
10
|
-
|
|
10
|
+
# Find hosts with subscription facets but without insights facets
|
|
11
|
+
# Note: We can't use scoped_search 'null? insights_uuid' because the null? operator
|
|
12
|
+
# doesn't work with ext_methods - it would check hosts.id IS NULL instead of the facet
|
|
13
|
+
hosts_without_facets = ::ForemanInventoryUpload::Generators::Queries.for_org(organization, use_batches: false)
|
|
14
|
+
.left_outer_joins(:insights)
|
|
15
|
+
.where(insights_facets: { id: nil })
|
|
16
|
+
|
|
11
17
|
facet_count = 0
|
|
12
|
-
hosts_without_facets.
|
|
18
|
+
hosts_without_facets.in_batches(of: ForemanInventoryUpload.slice_size) do |batch|
|
|
13
19
|
facets = batch.pluck(:id, 'katello_subscription_facets.uuid').map do |host_id, uuid|
|
|
14
20
|
{
|
|
15
21
|
host_id: host_id,
|
|
@@ -150,7 +150,7 @@ module ForemanRhCloud
|
|
|
150
150
|
end
|
|
151
151
|
|
|
152
152
|
::Foreman::Plugin.app_metadata_registry.register(:foreman_rh_cloud, {
|
|
153
|
-
iop: ForemanRhCloud.with_iop_smart_proxy
|
|
153
|
+
iop: -> { ForemanRhCloud.with_iop_smart_proxy? },
|
|
154
154
|
})
|
|
155
155
|
|
|
156
156
|
extend_template_helpers ForemanRhCloud::TemplateRendererHelper
|
data/package.json
CHANGED
|
@@ -188,4 +188,158 @@ class RhCloudHostTest < ActiveSupport::TestCase
|
|
|
188
188
|
assert_equal local_uuid, @host.insights_uuid
|
|
189
189
|
end
|
|
190
190
|
end
|
|
191
|
+
|
|
192
|
+
context 'scoped search on insights_uuid' do
|
|
193
|
+
setup do
|
|
194
|
+
@org = FactoryBot.create(:organization)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
teardown do
|
|
198
|
+
ForemanRhCloud.unstub(:with_iop_smart_proxy?)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
test 'searches insights_facet.uuid in non-IoP mode with = operator' do
|
|
202
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
203
|
+
host1 = FactoryBot.create(:host, :managed, organization: @org)
|
|
204
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'insights-uuid-123')
|
|
205
|
+
host2 = FactoryBot.create(:host, :managed, organization: @org)
|
|
206
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'insights-uuid-456')
|
|
207
|
+
|
|
208
|
+
results = Host::Managed.search_for('insights_uuid = insights-uuid-123')
|
|
209
|
+
|
|
210
|
+
assert_includes results, host1
|
|
211
|
+
assert_not_includes results, host2
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
test 'searches subscription_facet.uuid in IoP mode with = operator' do
|
|
215
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
216
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
217
|
+
host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
218
|
+
|
|
219
|
+
# Even if insights_facet has different UUID, should use subscription_facet UUID
|
|
220
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'stale-123')
|
|
221
|
+
|
|
222
|
+
results = Host::Managed.search_for("insights_uuid = #{host1.subscription_facet.uuid}")
|
|
223
|
+
|
|
224
|
+
assert_includes results, host1
|
|
225
|
+
assert_not_includes results, host2
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
test 'searches with ^ operator (IN) in non-IoP mode' do
|
|
229
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
230
|
+
host1 = FactoryBot.create(:host, :managed, organization: @org)
|
|
231
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'uuid-1')
|
|
232
|
+
host2 = FactoryBot.create(:host, :managed, organization: @org)
|
|
233
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'uuid-2')
|
|
234
|
+
host3 = FactoryBot.create(:host, :managed, organization: @org)
|
|
235
|
+
host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'uuid-3')
|
|
236
|
+
|
|
237
|
+
results = Host::Managed.search_for('insights_uuid ^ (uuid-1,uuid-2)')
|
|
238
|
+
|
|
239
|
+
assert_includes results, host1
|
|
240
|
+
assert_includes results, host2
|
|
241
|
+
assert_not_includes results, host3
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
test 'searches with ^ operator (IN) in IoP mode - THE BUG FIX' do
|
|
245
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
246
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
247
|
+
host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
248
|
+
host3 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
249
|
+
|
|
250
|
+
# Create insights facets with stale UUIDs to verify we're using subscription_facet
|
|
251
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'stale-1')
|
|
252
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'stale-2')
|
|
253
|
+
host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'stale-3')
|
|
254
|
+
|
|
255
|
+
uuid1 = host1.subscription_facet.uuid
|
|
256
|
+
uuid2 = host2.subscription_facet.uuid
|
|
257
|
+
|
|
258
|
+
# This is the search query that remediation modal creates
|
|
259
|
+
results = Host::Managed.search_for("insights_uuid ^ (#{uuid1},#{uuid2})")
|
|
260
|
+
|
|
261
|
+
# Should find hosts by subscription_facet UUID, not insights_facet UUID
|
|
262
|
+
assert_includes results, host1
|
|
263
|
+
assert_includes results, host2
|
|
264
|
+
assert_not_includes results, host3
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
test 'searches with !^ operator (NOT IN) in non-IoP mode' do
|
|
268
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
269
|
+
host1 = FactoryBot.create(:host, :managed, organization: @org)
|
|
270
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'uuid-1')
|
|
271
|
+
host2 = FactoryBot.create(:host, :managed, organization: @org)
|
|
272
|
+
host2.insights = FactoryBot.create(:insights_facet, host_id: host2.id, uuid: 'uuid-2')
|
|
273
|
+
host3 = FactoryBot.create(:host, :managed, organization: @org)
|
|
274
|
+
host3.insights = FactoryBot.create(:insights_facet, host_id: host3.id, uuid: 'uuid-3')
|
|
275
|
+
|
|
276
|
+
results = Host::Managed.search_for('insights_uuid !^ (uuid-1,uuid-2)')
|
|
277
|
+
|
|
278
|
+
assert_not_includes results, host1
|
|
279
|
+
assert_not_includes results, host2
|
|
280
|
+
assert_includes results, host3
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
test 'searches with !^ operator (NOT IN) in IoP mode' do
|
|
284
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
285
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
286
|
+
host2 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
287
|
+
host3 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
288
|
+
|
|
289
|
+
uuid1 = host1.subscription_facet.uuid
|
|
290
|
+
uuid2 = host2.subscription_facet.uuid
|
|
291
|
+
|
|
292
|
+
results = Host::Managed.search_for("insights_uuid !^ (#{uuid1},#{uuid2})")
|
|
293
|
+
|
|
294
|
+
assert_not_includes results, host1
|
|
295
|
+
assert_not_includes results, host2
|
|
296
|
+
assert_includes results, host3
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
test 'handles hosts without facets in non-IoP mode' do
|
|
300
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
301
|
+
host_without_facet = FactoryBot.create(:host, :managed, organization: @org)
|
|
302
|
+
host_with_facet = FactoryBot.create(:host, :managed, organization: @org)
|
|
303
|
+
host_with_facet.insights = FactoryBot.create(:insights_facet, host_id: host_with_facet.id, uuid: 'uuid-1')
|
|
304
|
+
|
|
305
|
+
results = Host::Managed.search_for('insights_uuid = uuid-1')
|
|
306
|
+
|
|
307
|
+
assert_includes results, host_with_facet
|
|
308
|
+
assert_not_includes results, host_without_facet
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
test 'handles hosts without subscription_facet in IoP mode' do
|
|
312
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
313
|
+
host_without_sub = FactoryBot.create(:host, :managed, organization: @org)
|
|
314
|
+
host_with_sub = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
315
|
+
|
|
316
|
+
uuid = host_with_sub.subscription_facet.uuid
|
|
317
|
+
|
|
318
|
+
results = Host::Managed.search_for("insights_uuid = #{uuid}")
|
|
319
|
+
|
|
320
|
+
assert_includes results, host_with_sub
|
|
321
|
+
assert_not_includes results, host_without_sub
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
test 'mode changes are reflected in searches' do
|
|
325
|
+
host1 = FactoryBot.create(:host, :managed, :with_subscription, organization: @org)
|
|
326
|
+
host1.insights = FactoryBot.create(:insights_facet, host_id: host1.id, uuid: 'insights-uuid-abc')
|
|
327
|
+
insights_uuid = 'insights-uuid-abc'
|
|
328
|
+
subscription_uuid = host1.subscription_facet.uuid
|
|
329
|
+
|
|
330
|
+
# Non-IoP mode: should find by insights_facet UUID
|
|
331
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(false)
|
|
332
|
+
results = Host::Managed.search_for("insights_uuid = #{insights_uuid}")
|
|
333
|
+
assert_includes results, host1
|
|
334
|
+
|
|
335
|
+
# IoP mode: should find by subscription_facet UUID
|
|
336
|
+
ForemanRhCloud.stubs(:with_iop_smart_proxy?).returns(true)
|
|
337
|
+
results = Host::Managed.search_for("insights_uuid = #{subscription_uuid}")
|
|
338
|
+
assert_includes results, host1
|
|
339
|
+
|
|
340
|
+
# Should NOT find by old insights_facet UUID in IoP mode
|
|
341
|
+
results = Host::Managed.search_for("insights_uuid = #{insights_uuid}")
|
|
342
|
+
assert_not_includes results, host1
|
|
343
|
+
end
|
|
344
|
+
end
|
|
191
345
|
end
|
|
@@ -32,13 +32,28 @@ const NewHostDetailsTab = ({ hostName, router }) => {
|
|
|
32
32
|
const hits = useSelector(selectHits);
|
|
33
33
|
const isIop = useIopConfig();
|
|
34
34
|
|
|
35
|
-
useEffect(
|
|
35
|
+
useEffect(
|
|
36
|
+
() => () => {
|
|
37
|
+
// Preserve hash when clearing search params to prevent tab navigation bugs
|
|
38
|
+
if (router && typeof router.replace === 'function') {
|
|
39
|
+
const replaceOptions = { search: null };
|
|
40
|
+
if (router.location && router.location.hash) {
|
|
41
|
+
replaceOptions.hash = router.location.hash;
|
|
42
|
+
}
|
|
43
|
+
router.replace(replaceOptions);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
[router]
|
|
47
|
+
);
|
|
36
48
|
|
|
37
49
|
const onSearch = q => dispatch(fetchInsights({ query: q, page: 1 }));
|
|
38
50
|
|
|
39
51
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
40
|
-
const onSatInsightsClick = () =>
|
|
41
|
-
router.push
|
|
52
|
+
const onSatInsightsClick = () => {
|
|
53
|
+
if (router && typeof router.push === 'function') {
|
|
54
|
+
router.push({ pathname: '/foreman_rh_cloud/insights_cloud' });
|
|
55
|
+
}
|
|
56
|
+
};
|
|
42
57
|
|
|
43
58
|
const dropdownItems = [
|
|
44
59
|
<DropdownItem key="insights-link" ouiaId="insights-link">
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
import '@testing-library/jest-dom';
|
|
4
|
+
import { Provider } from 'react-redux';
|
|
5
|
+
import configureMockStore from 'redux-mock-store';
|
|
6
|
+
import thunk from 'redux-thunk';
|
|
7
|
+
import NewHostDetailsTab from '../NewHostDetailsTab';
|
|
8
|
+
|
|
9
|
+
jest.mock('../../common/Hooks/ConfigHooks', () => ({
|
|
10
|
+
useIopConfig: jest.fn(() => false),
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
jest.mock('foremanReact/common/I18n', () => ({
|
|
14
|
+
translate: jest.fn(str => str),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
const mockStore = configureMockStore([thunk]);
|
|
18
|
+
|
|
19
|
+
describe('NewHostDetailsTab', () => {
|
|
20
|
+
let store;
|
|
21
|
+
let mockRouter;
|
|
22
|
+
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
mockRouter = {
|
|
25
|
+
push: jest.fn(),
|
|
26
|
+
replace: jest.fn(),
|
|
27
|
+
location: {
|
|
28
|
+
pathname: '/new/hosts/test-host.example.com',
|
|
29
|
+
search: '?page=1&per_page=20',
|
|
30
|
+
hash: '#/Insights',
|
|
31
|
+
query: { page: '1', per_page: '20' },
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
store = mockStore({
|
|
36
|
+
API: {},
|
|
37
|
+
ForemanRhCloud: {
|
|
38
|
+
InsightsCloudSync: {
|
|
39
|
+
table: {
|
|
40
|
+
selectedIds: {},
|
|
41
|
+
isAllSelected: false,
|
|
42
|
+
showSelectAllAlert: false,
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
insightsHostDetailsTab: {
|
|
47
|
+
query: '',
|
|
48
|
+
hits: [],
|
|
49
|
+
selectedIds: {},
|
|
50
|
+
error: null,
|
|
51
|
+
},
|
|
52
|
+
router: {
|
|
53
|
+
location: {
|
|
54
|
+
pathname: '/new/hosts/test-host.example.com',
|
|
55
|
+
search: '?page=1&per_page=20',
|
|
56
|
+
hash: '#/Insights',
|
|
57
|
+
query: { page: '1', per_page: '20' },
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
afterEach(() => {
|
|
64
|
+
jest.clearAllMocks();
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('cleanup effect', () => {
|
|
68
|
+
it('should preserve hash when clearing search params on unmount', () => {
|
|
69
|
+
const { unmount } = render(
|
|
70
|
+
<Provider store={store}>
|
|
71
|
+
<NewHostDetailsTab
|
|
72
|
+
hostName="test-host.example.com"
|
|
73
|
+
router={mockRouter}
|
|
74
|
+
/>
|
|
75
|
+
</Provider>
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
// Unmount the component to trigger cleanup
|
|
79
|
+
unmount();
|
|
80
|
+
|
|
81
|
+
// Verify router.replace was called with both search: null AND the existing hash
|
|
82
|
+
expect(mockRouter.replace).toHaveBeenCalledWith({
|
|
83
|
+
search: null,
|
|
84
|
+
hash: '#/Insights',
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it('should only clear search params when no hash exists', () => {
|
|
89
|
+
mockRouter.location.hash = '';
|
|
90
|
+
|
|
91
|
+
const { unmount } = render(
|
|
92
|
+
<Provider store={store}>
|
|
93
|
+
<NewHostDetailsTab
|
|
94
|
+
hostName="test-host.example.com"
|
|
95
|
+
router={mockRouter}
|
|
96
|
+
/>
|
|
97
|
+
</Provider>
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
unmount();
|
|
101
|
+
|
|
102
|
+
// When there's no hash, should only pass search: null
|
|
103
|
+
expect(mockRouter.replace).toHaveBeenCalledWith({
|
|
104
|
+
search: null,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should handle router.location being undefined gracefully', () => {
|
|
109
|
+
const routerWithoutLocation = {
|
|
110
|
+
push: jest.fn(),
|
|
111
|
+
replace: jest.fn(),
|
|
112
|
+
location: undefined,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const { unmount } = render(
|
|
116
|
+
<Provider store={store}>
|
|
117
|
+
<NewHostDetailsTab
|
|
118
|
+
hostName="test-host.example.com"
|
|
119
|
+
router={routerWithoutLocation}
|
|
120
|
+
/>
|
|
121
|
+
</Provider>
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
unmount();
|
|
125
|
+
|
|
126
|
+
// Should still call replace with search: null even if location is undefined
|
|
127
|
+
expect(routerWithoutLocation.replace).toHaveBeenCalledWith({
|
|
128
|
+
search: null,
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('should use the latest hash value at unmount time, not a stale captured value', () => {
|
|
133
|
+
const { unmount } = render(
|
|
134
|
+
<Provider store={store}>
|
|
135
|
+
<NewHostDetailsTab
|
|
136
|
+
hostName="test-host.example.com"
|
|
137
|
+
router={mockRouter}
|
|
138
|
+
/>
|
|
139
|
+
</Provider>
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// Change the hash after mount, before unmount
|
|
143
|
+
mockRouter.location.hash = '#/Overview';
|
|
144
|
+
|
|
145
|
+
unmount();
|
|
146
|
+
|
|
147
|
+
// Verify router.replace was called with the UPDATED hash, not the initial '#/Insights'
|
|
148
|
+
expect(mockRouter.replace).toHaveBeenCalledWith({
|
|
149
|
+
search: null,
|
|
150
|
+
hash: '#/Overview',
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
});
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: foreman_rh_cloud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 12.2.
|
|
4
|
+
version: 12.2.17
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Foreman Red Hat Cloud team
|
|
@@ -629,6 +629,7 @@ files:
|
|
|
629
629
|
- webpack/InsightsHostDetailsTab/__tests__/InsightsTabReducer.test.js
|
|
630
630
|
- webpack/InsightsHostDetailsTab/__tests__/InsightsTabSelectors.test.js
|
|
631
631
|
- webpack/InsightsHostDetailsTab/__tests__/InsightsTotalRiskChart.test.js
|
|
632
|
+
- webpack/InsightsHostDetailsTab/__tests__/NewHostDetailsTab.test.js
|
|
632
633
|
- webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTab.test.js.snap
|
|
633
634
|
- webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabActions.test.js.snap
|
|
634
635
|
- webpack/InsightsHostDetailsTab/__tests__/__snapshots__/InsightsTabReducer.test.js.snap
|
|
@@ -701,7 +702,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
701
702
|
- !ruby/object:Gem::Version
|
|
702
703
|
version: '0'
|
|
703
704
|
requirements: []
|
|
704
|
-
rubygems_version: 4.0.
|
|
705
|
+
rubygems_version: 4.0.6
|
|
705
706
|
specification_version: 4
|
|
706
707
|
summary: Summary of ForemanRhCloud.
|
|
707
708
|
test_files:
|