Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
f693a63b
Commit
f693a63b
authored
Apr 06, 2022
by
Illya Klymov
Committed by
Natalia Tepluhina
Apr 06, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement detailed github status reporting
* expose github stats data to user Changelog: added
parent
cbc35aaa
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
349 additions
and
54 deletions
+349
-54
app/assets/javascripts/import_entities/components/import_status.vue
.../javascripts/import_entities/components/import_status.vue
+129
-4
app/assets/javascripts/import_entities/constants.js
app/assets/javascripts/import_entities/constants.js
+0
-41
app/assets/javascripts/import_entities/import_projects/components/provider_repo_table_row.vue
...es/import_projects/components/provider_repo_table_row.vue
+9
-5
app/assets/javascripts/import_entities/import_projects/store/mutations.js
...cripts/import_entities/import_projects/store/mutations.js
+5
-1
app/assets/stylesheets/page_bundles/import.scss
app/assets/stylesheets/page_bundles/import.scss
+7
-3
locale/gitlab.pot
locale/gitlab.pot
+18
-0
spec/frontend/import_entities/components/import_status_spec.js
...frontend/import_entities/components/import_status_spec.js
+145
-0
spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
...mport_projects/components/provider_repo_table_row_spec.js
+7
-0
spec/frontend/import_entities/import_projects/store/mutations_spec.js
...d/import_entities/import_projects/store/mutations_spec.js
+29
-0
No files found.
app/assets/javascripts/import_entities/components/import_status.vue
View file @
f693a63b
<
script
>
<
script
>
import
{
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
GlAccordion
,
GlAccordionItem
,
GlBadge
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
STATUS_MAP
from
'
../constants
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
__
,
s__
}
from
'
~/locale
'
;
import
{
STATUSES
}
from
'
../constants
'
;
const
STATISTIC_ITEMS
=
{
diff_note
:
__
(
'
Diff notes
'
),
issue
:
__
(
'
Issues
'
),
label
:
__
(
'
Labels
'
),
milestone
:
__
(
'
Milestones
'
),
note
:
__
(
'
Notes
'
),
pull_request
:
s__
(
'
GithubImporter|Pull requests
'
),
pull_request_merged_by
:
s__
(
'
GithubImporter|PR mergers
'
),
pull_request_review
:
s__
(
'
GithubImporter|PR reviews
'
),
release
:
__
(
'
Releases
'
),
};
// support both camel case and snake case versions
Object
.
assign
(
STATISTIC_ITEMS
,
convertObjectPropsToCamelCase
(
STATISTIC_ITEMS
));
const
SCHEDULED_STATUS
=
{
icon
:
'
status-scheduled
'
,
text
:
__
(
'
Pending
'
),
variant
:
'
muted
'
,
};
const
STATUS_MAP
=
{
[
STATUSES
.
NONE
]:
{
icon
:
'
status-waiting
'
,
text
:
__
(
'
Not started
'
),
variant
:
'
muted
'
,
},
[
STATUSES
.
SCHEDULING
]:
SCHEDULED_STATUS
,
[
STATUSES
.
SCHEDULED
]:
SCHEDULED_STATUS
,
[
STATUSES
.
CREATED
]:
SCHEDULED_STATUS
,
[
STATUSES
.
STARTED
]:
{
icon
:
'
status-running
'
,
text
:
__
(
'
Importing...
'
),
variant
:
'
info
'
,
},
[
STATUSES
.
FAILED
]:
{
icon
:
'
status-failed
'
,
text
:
__
(
'
Failed
'
),
variant
:
'
danger
'
,
},
[
STATUSES
.
CANCELLED
]:
{
icon
:
'
status-stopped
'
,
text
:
__
(
'
Cancelled
'
),
variant
:
'
neutral
'
,
},
};
function
isIncompleteImport
(
stats
)
{
return
Object
.
keys
(
stats
.
fetched
).
some
((
key
)
=>
stats
.
fetched
[
key
]
!==
stats
.
imported
[
key
]);
}
export
default
{
export
default
{
name
:
'
ImportStatus
'
,
name
:
'
ImportStatus
'
,
components
:
{
components
:
{
GlAccordion
,
GlAccordionItem
,
GlBadge
,
GlIcon
,
GlIcon
,
},
},
props
:
{
props
:
{
...
@@ -12,19 +68,88 @@ export default {
...
@@ -12,19 +68,88 @@ export default {
type
:
String
,
type
:
String
,
required
:
true
,
required
:
true
,
},
},
stats
:
{
type
:
Object
,
required
:
false
,
default
:
()
=>
({
fetched
:
{},
imported
:
{}
}),
},
},
},
computed
:
{
computed
:
{
knownStats
()
{
const
knownStatisticKeys
=
Object
.
keys
(
STATISTIC_ITEMS
);
return
Object
.
keys
(
this
.
stats
.
fetched
).
filter
((
key
)
=>
knownStatisticKeys
.
includes
(
key
));
},
hasStats
()
{
return
this
.
stats
&&
this
.
knownStats
.
length
>
0
;
},
mappedStatus
()
{
mappedStatus
()
{
if
(
this
.
status
===
STATUSES
.
FINISHED
)
{
const
isIncomplete
=
this
.
stats
&&
isIncompleteImport
(
this
.
stats
);
return
{
icon
:
'
status-success
'
,
...(
isIncomplete
?
{
text
:
__
(
'
Partial import
'
),
variant
:
'
warning
'
,
}
:
{
text
:
__
(
'
Complete
'
),
variant
:
'
success
'
,
}),
};
}
return
STATUS_MAP
[
this
.
status
];
return
STATUS_MAP
[
this
.
status
];
},
},
},
},
methods
:
{
getStatisticIconProps
(
key
)
{
const
fetched
=
this
.
stats
.
fetched
[
key
];
const
imported
=
this
.
stats
.
imported
[
key
];
if
(
fetched
===
imported
)
{
return
{
name
:
'
status-success
'
,
class
:
'
gl-text-green-400
'
};
}
else
if
(
imported
===
0
)
{
return
{
name
:
'
status-scheduled
'
,
class
:
'
gl-text-gray-400
'
};
}
return
{
name
:
'
status-running
'
,
class
:
'
gl-text-blue-400
'
};
},
},
STATISTIC_ITEMS
,
};
};
</
script
>
</
script
>
<
template
>
<
template
>
<div>
<div>
<gl-icon
:name=
"mappedStatus.icon"
:class=
"mappedStatus.iconClass"
:size=
"12"
class=
"gl-mr-2"
/>
<div
class=
"gl-display-inline-block gl-w-13"
>
<span>
{{
mappedStatus
.
text
}}
</span>
<gl-badge
:icon=
"mappedStatus.icon"
:variant=
"mappedStatus.variant"
size=
"md"
class=
"gl-mr-2"
>
{{
mappedStatus
.
text
}}
</gl-badge>
</div>
<gl-accordion
v-if=
"hasStats"
:header-level=
"3"
>
<gl-accordion-item
:title=
"__('Details')"
>
<ul
class=
"gl-p-0 gl-list-style-none gl-font-sm"
>
<li
v-for=
"key in knownStats"
:key=
"key"
>
<div
class=
"gl-display-flex gl-w-20 gl-align-items-center"
>
<gl-icon
:size=
"12"
class=
"gl-mr-3 gl-flex-shrink-0"
v-bind=
"getStatisticIconProps(key)"
/>
<span
class=
""
>
{{
$options
.
STATISTIC_ITEMS
[
key
]
}}
</span>
<span
class=
"gl-ml-auto"
>
{{
stats
.
imported
[
key
]
||
0
}}
/
{{
stats
.
fetched
[
key
]
}}
</span>
</div>
</li>
</ul>
</gl-accordion-item>
</gl-accordion>
</div>
</div>
</
template
>
</
template
>
app/assets/javascripts/import_entities/constants.js
View file @
f693a63b
import
{
__
}
from
'
~/locale
'
;
// The `scheduling` status is only present on the client-side,
// The `scheduling` status is only present on the client-side,
// it is used as the status when we are requesting to start an import.
// it is used as the status when we are requesting to start an import.
...
@@ -13,42 +11,3 @@ export const STATUSES = {
...
@@ -13,42 +11,3 @@ export const STATUSES = {
SCHEDULING
:
'
scheduling
'
,
SCHEDULING
:
'
scheduling
'
,
CANCELLED
:
'
cancelled
'
,
CANCELLED
:
'
cancelled
'
,
};
};
const
SCHEDULED_STATUS
=
{
icon
:
'
status-scheduled
'
,
text
:
__
(
'
Pending
'
),
iconClass
:
'
gl-text-orange-400
'
,
};
const
STATUS_MAP
=
{
[
STATUSES
.
NONE
]:
{
icon
:
'
status-waiting
'
,
text
:
__
(
'
Not started
'
),
iconClass
:
'
gl-text-gray-400
'
,
},
[
STATUSES
.
SCHEDULING
]:
SCHEDULED_STATUS
,
[
STATUSES
.
SCHEDULED
]:
SCHEDULED_STATUS
,
[
STATUSES
.
CREATED
]:
SCHEDULED_STATUS
,
[
STATUSES
.
STARTED
]:
{
icon
:
'
status-running
'
,
text
:
__
(
'
Importing...
'
),
iconClass
:
'
gl-text-blue-400
'
,
},
[
STATUSES
.
FINISHED
]:
{
icon
:
'
status-success
'
,
text
:
__
(
'
Complete
'
),
iconClass
:
'
gl-text-green-400
'
,
},
[
STATUSES
.
FAILED
]:
{
icon
:
'
status-failed
'
,
text
:
__
(
'
Failed
'
),
iconClass
:
'
gl-text-red-600
'
,
},
[
STATUSES
.
CANCELLED
]:
{
icon
:
'
status-stopped
'
,
text
:
__
(
'
Cancelled
'
),
iconClass
:
'
gl-text-red-600
'
,
},
};
export
default
STATUS_MAP
;
app/assets/javascripts/import_entities/import_projects/components/provider_repo_table_row.vue
View file @
f693a63b
...
@@ -69,6 +69,10 @@ export default {
...
@@ -69,6 +69,10 @@ export default {
return
getImportStatus
(
this
.
repo
);
return
getImportStatus
(
this
.
repo
);
},
},
stats
()
{
return
this
.
repo
.
importedProject
?.
stats
;
},
importTarget
()
{
importTarget
()
{
return
this
.
getImportTarget
(
this
.
repo
.
importSource
.
id
);
return
this
.
getImportTarget
(
this
.
repo
.
importSource
.
id
);
},
},
...
@@ -101,11 +105,11 @@ export default {
...
@@ -101,11 +105,11 @@ export default {
<
template
>
<
template
>
<tr
<tr
class=
"gl-h-11 gl-border-0 gl-border-solid gl-border-t-1 gl-border-gray-100 gl-h-11"
class=
"gl-h-11 gl-border-0 gl-border-solid gl-border-t-1 gl-border-gray-100 gl-h-11
gl-vertical-align-top
"
data-qa-selector=
"project_import_row"
data-qa-selector=
"project_import_row"
:data-qa-source-project=
"repo.importSource.fullName"
:data-qa-source-project=
"repo.importSource.fullName"
>
>
<td
class=
"gl-p-4"
>
<td
class=
"gl-p-4
gl-vertical-align-top
"
>
<gl-link
:href=
"repo.importSource.providerLink"
target=
"_blank"
data-testid=
"providerLink"
<gl-link
:href=
"repo.importSource.providerLink"
target=
"_blank"
data-testid=
"providerLink"
>
{{
repo
.
importSource
.
fullName
}}
>
{{
repo
.
importSource
.
fullName
}}
<gl-icon
v-if=
"repo.importSource.providerLink"
name=
"external-link"
/>
<gl-icon
v-if=
"repo.importSource.providerLink"
name=
"external-link"
/>
...
@@ -156,10 +160,10 @@ export default {
...
@@ -156,10 +160,10 @@ export default {
</template>
</template>
<
template
v-else-if=
"repo.importedProject"
>
{{
displayFullPath
}}
</
template
>
<
template
v-else-if=
"repo.importedProject"
>
{{
displayFullPath
}}
</
template
>
</td>
</td>
<td
class=
"gl-p-4"
data-qa-selector=
"import_status_indicator"
>
<td
class=
"gl-p-4
gl-vertical-align-top
"
data-qa-selector=
"import_status_indicator"
>
<import-status
:status=
"importStatus"
/>
<import-status
:status=
"importStatus"
:stats=
"stats"
/>
</td>
</td>
<td
data-testid=
"actions"
>
<td
data-testid=
"actions"
class=
"gl-vertical-align-top gl-pt-4"
>
<gl-button
<gl-button
v-if=
"isFinished"
v-if=
"isFinished"
class=
"btn btn-default"
class=
"btn btn-default"
...
...
app/assets/javascripts/import_entities/import_projects/store/mutations.js
View file @
f693a63b
...
@@ -113,7 +113,11 @@ export default {
...
@@ -113,7 +113,11 @@ export default {
updatedProjects
.
forEach
((
updatedProject
)
=>
{
updatedProjects
.
forEach
((
updatedProject
)
=>
{
const
repo
=
state
.
repositories
.
find
((
p
)
=>
p
.
importedProject
?.
id
===
updatedProject
.
id
);
const
repo
=
state
.
repositories
.
find
((
p
)
=>
p
.
importedProject
?.
id
===
updatedProject
.
id
);
if
(
repo
?.
importedProject
)
{
if
(
repo
?.
importedProject
)
{
repo
.
importedProject
.
importStatus
=
updatedProject
.
importStatus
;
repo
.
importedProject
=
{
...
repo
.
importedProject
,
stats
:
updatedProject
.
stats
,
importStatus
:
updatedProject
.
importStatus
,
};
}
}
});
});
},
},
...
...
app/assets/stylesheets/page_bundles/import.scss
View file @
f693a63b
@import
'mixins_and_variables_and_functions'
;
@import
'mixins_and_variables_and_functions'
;
.import-jobs-from-col
{
width
:
37%
;
}
.import-jobs-to-col
{
.import-jobs-to-col
{
width
:
3
9
%
;
width
:
3
7
%
;
}
}
.import-jobs-status-col
{
.import-jobs-status-col
{
width
:
1
5%
;
width
:
2
5%
;
}
}
.import-jobs-cta-col
{
.import-jobs-cta-col
{
width
:
1%
;
width
:
1%
;
}
}
.import-entities-target-select
{
.import-entities-target-select
{
&
.disabled
{
&
.disabled
{
.import-entities-target-select-separator
{
.import-entities-target-select-separator
{
...
...
locale/gitlab.pot
View file @
f693a63b
...
@@ -13016,6 +13016,9 @@ msgstr ""
...
@@ -13016,6 +13016,9 @@ msgstr ""
msgid "Diff limits"
msgid "Diff limits"
msgstr ""
msgstr ""
msgid "Diff notes"
msgstr ""
msgid "Difference between start date and now"
msgid "Difference between start date and now"
msgstr ""
msgstr ""
...
@@ -17085,6 +17088,15 @@ msgstr ""
...
@@ -17085,6 +17088,15 @@ msgstr ""
msgid "Gitea Import"
msgid "Gitea Import"
msgstr ""
msgstr ""
msgid "GithubImporter|PR mergers"
msgstr ""
msgid "GithubImporter|PR reviews"
msgstr ""
msgid "GithubImporter|Pull requests"
msgstr ""
msgid "GithubIntegration|Create a %{token_link_start}personal access token%{token_link_end} with %{status_html} access granted and paste it here."
msgid "GithubIntegration|Create a %{token_link_start}personal access token%{token_link_end} with %{status_html} access granted and paste it here."
msgstr ""
msgstr ""
...
@@ -25642,6 +25654,9 @@ msgstr ""
...
@@ -25642,6 +25654,9 @@ msgstr ""
msgid "NoteForm|Note"
msgid "NoteForm|Note"
msgstr ""
msgstr ""
msgid "Notes"
msgstr ""
msgid "Notes rate limit"
msgid "Notes rate limit"
msgstr ""
msgstr ""
...
@@ -27010,6 +27025,9 @@ msgstr ""
...
@@ -27010,6 +27025,9 @@ msgstr ""
msgid "Part of merge request changes"
msgid "Part of merge request changes"
msgstr ""
msgstr ""
msgid "Partial import"
msgstr ""
msgid "Participants"
msgid "Participants"
msgstr ""
msgstr ""
...
...
spec/frontend/import_entities/components/import_status_spec.js
0 → 100644
View file @
f693a63b
import
{
GlAccordionItem
,
GlBadge
,
GlIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
ImportStatus
from
'
~/import_entities/components/import_status.vue
'
;
import
{
STATUSES
}
from
'
~/import_entities/constants
'
;
describe
(
'
Import entities status component
'
,
()
=>
{
let
wrapper
;
const
createComponent
=
(
propsData
)
=>
{
wrapper
=
shallowMount
(
ImportStatus
,
{
propsData
,
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
describe
(
'
success status
'
,
()
=>
{
const
getStatusText
=
()
=>
wrapper
.
findComponent
(
GlBadge
).
text
();
it
(
'
displays finished status as complete when no stats are provided
'
,
()
=>
{
createComponent
({
status
:
STATUSES
.
FINISHED
,
});
expect
(
getStatusText
()).
toBe
(
'
Complete
'
);
});
it
(
'
displays finished status as complete when all stats items were processed
'
,
()
=>
{
const
statItems
=
{
label
:
100
,
note
:
200
};
createComponent
({
status
:
STATUSES
.
FINISHED
,
stats
:
{
fetched
:
{
...
statItems
},
imported
:
{
...
statItems
},
},
});
expect
(
getStatusText
()).
toBe
(
'
Complete
'
);
});
it
(
'
displays finished status as partial when all stats items were processed
'
,
()
=>
{
const
statItems
=
{
label
:
100
,
note
:
200
};
createComponent
({
status
:
STATUSES
.
FINISHED
,
stats
:
{
fetched
:
{
...
statItems
},
imported
:
{
...
statItems
,
label
:
50
},
},
});
expect
(
getStatusText
()).
toBe
(
'
Partial import
'
);
});
});
describe
(
'
details drawer
'
,
()
=>
{
const
findDetailsDrawer
=
()
=>
wrapper
.
findComponent
(
GlAccordionItem
);
it
(
'
renders details drawer to be present when stats are provided
'
,
()
=>
{
createComponent
({
status
:
'
created
'
,
stats
:
{
fetched
:
{
label
:
1
},
imported
:
{
label
:
0
}
},
});
expect
(
findDetailsDrawer
().
exists
()).
toBe
(
true
);
});
it
(
'
does not render details drawer when no stats are provided
'
,
()
=>
{
createComponent
({
status
:
'
created
'
,
});
expect
(
findDetailsDrawer
().
exists
()).
toBe
(
false
);
});
it
(
'
does not render details drawer when stats are empty
'
,
()
=>
{
createComponent
({
status
:
'
created
'
,
stats
:
{
fetched
:
{},
imported
:
{}
},
});
expect
(
findDetailsDrawer
().
exists
()).
toBe
(
false
);
});
it
(
'
does not render details drawer when no known stats are provided
'
,
()
=>
{
createComponent
({
status
:
'
created
'
,
stats
:
{
fetched
:
{
UNKNOWN_STAT
:
100
,
},
imported
:
{
UNKNOWN_STAT
:
0
,
},
},
});
expect
(
findDetailsDrawer
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
stats display
'
,
()
=>
{
const
getStatusIcon
=
()
=>
wrapper
.
findComponent
(
GlAccordionItem
).
findComponent
(
GlIcon
).
props
().
name
;
const
createComponentWithStats
=
({
fetched
,
imported
})
=>
{
createComponent
({
status
:
'
created
'
,
stats
:
{
fetched
:
{
label
:
fetched
},
imported
:
{
label
:
imported
},
},
});
};
it
(
'
displays scheduled status when imported is 0
'
,
()
=>
{
createComponentWithStats
({
fetched
:
100
,
imported
:
0
,
});
expect
(
getStatusIcon
()).
toBe
(
'
status-scheduled
'
);
});
it
(
'
displays running status when imported is not equal to fetched
'
,
()
=>
{
createComponentWithStats
({
fetched
:
100
,
imported
:
10
,
});
expect
(
getStatusIcon
()).
toBe
(
'
status-running
'
);
});
it
(
'
displays success status when imported is equal to fetched
'
,
()
=>
{
createComponentWithStats
({
fetched
:
100
,
imported
:
100
,
});
expect
(
getStatusIcon
()).
toBe
(
'
status-success
'
);
});
});
});
spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
View file @
f693a63b
...
@@ -98,6 +98,8 @@ describe('ProviderRepoTableRow', () => {
...
@@ -98,6 +98,8 @@ describe('ProviderRepoTableRow', () => {
});
});
describe
(
'
when rendering imported project
'
,
()
=>
{
describe
(
'
when rendering imported project
'
,
()
=>
{
const
FAKE_STATS
=
{};
const
repo
=
{
const
repo
=
{
importSource
:
{
importSource
:
{
id
:
'
remote-1
'
,
id
:
'
remote-1
'
,
...
@@ -109,6 +111,7 @@ describe('ProviderRepoTableRow', () => {
...
@@ -109,6 +111,7 @@ describe('ProviderRepoTableRow', () => {
fullPath
:
'
fullPath
'
,
fullPath
:
'
fullPath
'
,
importSource
:
'
importSource
'
,
importSource
:
'
importSource
'
,
importStatus
:
STATUSES
.
FINISHED
,
importStatus
:
STATUSES
.
FINISHED
,
stats
:
FAKE_STATS
,
},
},
};
};
...
@@ -134,6 +137,10 @@ describe('ProviderRepoTableRow', () => {
...
@@ -134,6 +137,10 @@ describe('ProviderRepoTableRow', () => {
it
(
'
does not render import button
'
,
()
=>
{
it
(
'
does not render import button
'
,
()
=>
{
expect
(
findImportButton
().
exists
()).
toBe
(
false
);
expect
(
findImportButton
().
exists
()).
toBe
(
false
);
});
});
it
(
'
passes stats to import status component
'
,
()
=>
{
expect
(
wrapper
.
find
(
ImportStatus
).
props
().
stats
).
toBe
(
FAKE_STATS
);
});
});
});
describe
(
'
when rendering incompatible project
'
,
()
=>
{
describe
(
'
when rendering incompatible project
'
,
()
=>
{
...
...
spec/frontend/import_entities/import_projects/store/mutations_spec.js
View file @
f693a63b
...
@@ -232,6 +232,35 @@ describe('import_projects store mutations', () => {
...
@@ -232,6 +232,35 @@ describe('import_projects store mutations', () => {
updatedProjects
[
0
].
importStatus
,
updatedProjects
[
0
].
importStatus
,
);
);
});
});
it
(
'
updates import stats of project
'
,
()
=>
{
const
repoId
=
1
;
state
=
{
repositories
:
[
{
importedProject
:
{
id
:
repoId
,
stats
:
{}
},
importStatus
:
STATUSES
.
STARTED
},
],
};
const
newStats
=
{
fetched
:
{
label
:
10
,
},
imported
:
{
label
:
1
,
},
};
const
updatedProjects
=
[
{
id
:
repoId
,
importStatus
:
STATUSES
.
FINISHED
,
stats
:
newStats
,
},
];
mutations
[
types
.
RECEIVE_JOBS_SUCCESS
](
state
,
updatedProjects
);
expect
(
state
.
repositories
[
0
].
importedProject
.
stats
).
toStrictEqual
(
newStats
);
});
});
});
describe
(
`
${
types
.
REQUEST_NAMESPACES
}
`
,
()
=>
{
describe
(
`
${
types
.
REQUEST_NAMESPACES
}
`
,
()
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment