提交 4167f19b 编写于 作者: T Tim Zallmann 提交者: Filipa Lacerda

Upgraded all vue libraries

上级 11463bf9
...@@ -99,7 +99,7 @@ export default { ...@@ -99,7 +99,7 @@ export default {
> >
<div <div
v-if="model.isLoadingFolderContent" v-if="model.isLoadingFolderContent"
:key="i"> :key="`loading-item-${i}`">
<loading-icon size="2" /> <loading-icon size="2" />
</div> </div>
...@@ -110,10 +110,10 @@ export default { ...@@ -110,10 +110,10 @@ export default {
:model="children" :model="children"
:can-create-deployment="canCreateDeployment" :can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment" :can-read-environment="canReadEnvironment"
:key="index" :key="`env-item-${i}-${index}`"
/> />
<div :key="i"> <div :key="`sub-div-${i}`">
<div class="text-center prepend-top-10"> <div class="text-center prepend-top-10">
<a <a
:href="folderUrl(model)" :href="folderUrl(model)"
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
> >
<repo-tab <repo-tab
v-for="tab in openFiles" v-for="tab in openFiles"
:key="tab.id" :key="tab.key"
:tab="tab" :tab="tab"
/> />
</ul> </ul>
......
...@@ -184,9 +184,9 @@ describe('Board list component', () => { ...@@ -184,9 +184,9 @@ describe('Board list component', () => {
component.$refs.list.style.height = '100px'; component.$refs.list.style.height = '100px';
component.$refs.list.style.overflow = 'scroll'; component.$refs.list.style.overflow = 'scroll';
for (let i = 0; i < 19; i += 1) { for (let i = 1; i < 20; i += 1) {
const issue = component.list.issues[0]; const issue = Object.assign({}, component.list.issues[0]);
issue.id += 1; issue.id += i;
component.list.issues.push(issue); component.list.issues.push(issue);
} }
......
...@@ -61,14 +61,14 @@ describe('pipeline graph job component', () => { ...@@ -61,14 +61,14 @@ describe('pipeline graph job component', () => {
it('it should render status and name', () => { it('it should render status and name', () => {
component = mountComponent(JobComponent, { component = mountComponent(JobComponent, {
job: { job: {
id: 4256, id: 4257,
name: 'test', name: 'test',
status: { status: {
icon: 'icon_status_success', icon: 'icon_status_success',
text: 'passed', text: 'passed',
label: 'passed', label: 'passed',
group: 'success', group: 'success',
details_path: '/root/ci-mock/builds/4256', details_path: '/root/ci-mock/builds/4257',
has_details: false, has_details: false,
}, },
}, },
...@@ -118,7 +118,7 @@ describe('pipeline graph job component', () => { ...@@ -118,7 +118,7 @@ describe('pipeline graph job component', () => {
it('should not render status label when it is not provided', () => { it('should not render status label when it is not provided', () => {
component = mountComponent(JobComponent, { component = mountComponent(JobComponent, {
job: { job: {
id: 4256, id: 4258,
name: 'test', name: 'test',
status: { status: {
icon: 'icon_status_success', icon: 'icon_status_success',
...@@ -132,7 +132,7 @@ describe('pipeline graph job component', () => { ...@@ -132,7 +132,7 @@ describe('pipeline graph job component', () => {
it('should not render status label when it is provided', () => { it('should not render status label when it is provided', () => {
component = mountComponent(JobComponent, { component = mountComponent(JobComponent, {
job: { job: {
id: 4256, id: 4259,
name: 'test', name: 'test',
status: { status: {
icon: 'icon_status_success', icon: 'icon_status_success',
......
...@@ -4,18 +4,18 @@ import stageColumnComponent from '~/pipelines/components/graph/stage_column_comp ...@@ -4,18 +4,18 @@ import stageColumnComponent from '~/pipelines/components/graph/stage_column_comp
describe('stage column component', () => { describe('stage column component', () => {
let component; let component;
const mockJob = { const mockJob = {
id: 4256, id: 4250,
name: 'test', name: 'test',
status: { status: {
icon: 'icon_status_success', icon: 'icon_status_success',
text: 'passed', text: 'passed',
label: 'passed', label: 'passed',
group: 'success', group: 'success',
details_path: '/root/ci-mock/builds/4256', details_path: '/root/ci-mock/builds/4250',
action: { action: {
icon: 'retry', icon: 'retry',
title: 'Retry', title: 'Retry',
path: '/root/ci-mock/builds/4256/retry', path: '/root/ci-mock/builds/4250/retry',
method: 'post', method: 'post',
}, },
}, },
...@@ -24,10 +24,17 @@ describe('stage column component', () => { ...@@ -24,10 +24,17 @@ describe('stage column component', () => {
beforeEach(() => { beforeEach(() => {
const StageColumnComponent = Vue.extend(stageColumnComponent); const StageColumnComponent = Vue.extend(stageColumnComponent);
const mockJobs = [];
for (let i = 0; i < 3; i += 1) {
const mockedJob = Object.assign({}, mockJob);
mockedJob.id += i;
mockJobs.push(mockedJob);
}
component = new StageColumnComponent({ component = new StageColumnComponent({
propsData: { propsData: {
title: 'foo', title: 'foo',
jobs: [mockJob, mockJob, mockJob], jobs: mockJobs,
}, },
}).$mount(); }).$mount();
}); });
......
...@@ -12,7 +12,7 @@ describe('Multi-file editor commit sidebar list collapsed', () => { ...@@ -12,7 +12,7 @@ describe('Multi-file editor commit sidebar list collapsed', () => {
vm = createComponentWithStore(Component, store); vm = createComponentWithStore(Component, store);
vm.$store.state.openFiles.push(file(), file()); vm.$store.state.openFiles.push(file('file1'), file('file2'));
vm.$store.state.openFiles[0].tempFile = true; vm.$store.state.openFiles[0].tempFile = true;
vm.$store.state.openFiles.forEach((f) => { vm.$store.state.openFiles.forEach((f) => {
Object.assign(f, { Object.assign(f, {
......
...@@ -10,7 +10,7 @@ describe('Multi-file editor commit sidebar list item', () => { ...@@ -10,7 +10,7 @@ describe('Multi-file editor commit sidebar list item', () => {
beforeEach(() => { beforeEach(() => {
const Component = Vue.extend(listItem); const Component = Vue.extend(listItem);
f = file(); f = file('test-file');
vm = mountComponent(Component, { vm = mountComponent(Component, {
file: f, file: f,
......
...@@ -29,7 +29,7 @@ describe('RepoCommitSection', () => { ...@@ -29,7 +29,7 @@ describe('RepoCommitSection', () => {
comp.$store.state.rightPanelCollapsed = false; comp.$store.state.rightPanelCollapsed = false;
comp.$store.state.currentBranch = 'master'; comp.$store.state.currentBranch = 'master';
comp.$store.state.openFiles = [file(), file()]; comp.$store.state.openFiles = [file('file1'), file('file2')];
comp.$store.state.openFiles.forEach(f => Object.assign(f, { comp.$store.state.openFiles.forEach(f => Object.assign(f, {
changed: true, changed: true,
content: 'testing', content: 'testing',
......
...@@ -25,7 +25,7 @@ describe('RepoFile', () => { ...@@ -25,7 +25,7 @@ describe('RepoFile', () => {
vm = new RepoFile({ vm = new RepoFile({
store, store,
propsData: { propsData: {
file: file(), file: file('t4'),
}, },
}); });
spyOn(vm, 'timeFormated').and.returnValue(updated); spyOn(vm, 'timeFormated').and.returnValue(updated);
...@@ -39,7 +39,7 @@ describe('RepoFile', () => { ...@@ -39,7 +39,7 @@ describe('RepoFile', () => {
it('does render if hasFiles is true and is loading tree', () => { it('does render if hasFiles is true and is loading tree', () => {
vm = createComponent({ vm = createComponent({
file: file(), file: file('t1'),
}); });
expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy(); expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy();
...@@ -47,7 +47,7 @@ describe('RepoFile', () => { ...@@ -47,7 +47,7 @@ describe('RepoFile', () => {
it('does not render commit message and datetime if mini', (done) => { it('does not render commit message and datetime if mini', (done) => {
vm = createComponent({ vm = createComponent({
file: file(), file: file('t2'),
}); });
vm.$store.state.openFiles.push(vm.file); vm.$store.state.openFiles.push(vm.file);
...@@ -61,7 +61,7 @@ describe('RepoFile', () => { ...@@ -61,7 +61,7 @@ describe('RepoFile', () => {
it('fires clickFile when the link is clicked', () => { it('fires clickFile when the link is clicked', () => {
vm = createComponent({ vm = createComponent({
file: file(), file: file('t3'),
}); });
spyOn(vm, 'clickFile'); spyOn(vm, 'clickFile');
......
...@@ -56,7 +56,7 @@ describe('RepoTab', () => { ...@@ -56,7 +56,7 @@ describe('RepoTab', () => {
}); });
it('renders an fa-circle icon if tab is changed', () => { it('renders an fa-circle icon if tab is changed', () => {
const tab = file(); const tab = file('changedFile');
tab.changed = true; tab.changed = true;
vm = createComponent({ vm = createComponent({
tab, tab,
...@@ -68,7 +68,7 @@ describe('RepoTab', () => { ...@@ -68,7 +68,7 @@ describe('RepoTab', () => {
describe('methods', () => { describe('methods', () => {
describe('closeTab', () => { describe('closeTab', () => {
it('does not close tab if is changed', (done) => { it('does not close tab if is changed', (done) => {
const tab = file(); const tab = file('closeFile');
tab.changed = true; tab.changed = true;
tab.opened = true; tab.opened = true;
vm = createComponent({ vm = createComponent({
......
...@@ -4,7 +4,7 @@ import repoTabs from '~/ide/components/repo_tabs.vue'; ...@@ -4,7 +4,7 @@ import repoTabs from '~/ide/components/repo_tabs.vue';
import { file, resetStore } from '../helpers'; import { file, resetStore } from '../helpers';
describe('RepoTabs', () => { describe('RepoTabs', () => {
const openedFiles = [file(), file()]; const openedFiles = [file('open1'), file('open2')];
let vm; let vm;
function createComponent() { function createComponent() {
......
...@@ -18,7 +18,7 @@ describe('Multi-file store file actions', () => { ...@@ -18,7 +18,7 @@ describe('Multi-file store file actions', () => {
oldGetLastCommitData = store._actions.getLastCommitData; // eslint-disable-line oldGetLastCommitData = store._actions.getLastCommitData; // eslint-disable-line
store._actions.getLastCommitData = [getLastCommitDataSpy]; // eslint-disable-line store._actions.getLastCommitData = [getLastCommitDataSpy]; // eslint-disable-line
localFile = file(); localFile = file('testFile');
localFile.active = true; localFile.active = true;
localFile.opened = true; localFile.opened = true;
localFile.parentTreeUrl = 'parentTreeUrl'; localFile.parentTreeUrl = 'parentTreeUrl';
...@@ -81,7 +81,7 @@ describe('Multi-file store file actions', () => { ...@@ -81,7 +81,7 @@ describe('Multi-file store file actions', () => {
}); });
it('sets next file as active', (done) => { it('sets next file as active', (done) => {
const f = file(); const f = file('otherfile');
store.state.openFiles.push(f); store.state.openFiles.push(f);
expect(f.active).toBeFalsy(); expect(f.active).toBeFalsy();
...@@ -119,7 +119,7 @@ describe('Multi-file store file actions', () => { ...@@ -119,7 +119,7 @@ describe('Multi-file store file actions', () => {
}); });
it('calls scrollToTab', (done) => { it('calls scrollToTab', (done) => {
store.dispatch('setFileActive', file()) store.dispatch('setFileActive', file('setThisActive'))
.then(() => { .then(() => {
expect(scrollToTabSpy).toHaveBeenCalled(); expect(scrollToTabSpy).toHaveBeenCalled();
...@@ -128,7 +128,7 @@ describe('Multi-file store file actions', () => { ...@@ -128,7 +128,7 @@ describe('Multi-file store file actions', () => {
}); });
it('sets the file active', (done) => { it('sets the file active', (done) => {
const localFile = file(); const localFile = file('activeFile');
store.dispatch('setFileActive', localFile) store.dispatch('setFileActive', localFile)
.then(() => { .then(() => {
...@@ -139,7 +139,7 @@ describe('Multi-file store file actions', () => { ...@@ -139,7 +139,7 @@ describe('Multi-file store file actions', () => {
}); });
it('returns early if file is already active', (done) => { it('returns early if file is already active', (done) => {
const localFile = file(); const localFile = file('earlyActive');
localFile.active = true; localFile.active = true;
store.dispatch('setFileActive', localFile) store.dispatch('setFileActive', localFile)
...@@ -151,11 +151,11 @@ describe('Multi-file store file actions', () => { ...@@ -151,11 +151,11 @@ describe('Multi-file store file actions', () => {
}); });
it('sets current active file to not active', (done) => { it('sets current active file to not active', (done) => {
const localFile = file(); const localFile = file('currentActive');
localFile.active = true; localFile.active = true;
store.state.openFiles.push(localFile); store.state.openFiles.push(localFile);
store.dispatch('setFileActive', file()) store.dispatch('setFileActive', file('newActive'))
.then(() => { .then(() => {
expect(localFile.active).toBeFalsy(); expect(localFile.active).toBeFalsy();
...@@ -166,7 +166,7 @@ describe('Multi-file store file actions', () => { ...@@ -166,7 +166,7 @@ describe('Multi-file store file actions', () => {
it('resets location.hash for line highlighting', (done) => { it('resets location.hash for line highlighting', (done) => {
location.hash = 'test'; location.hash = 'test';
store.dispatch('setFileActive', file()) store.dispatch('setFileActive', file('otherActive'))
.then(() => { .then(() => {
expect(location.hash).not.toBe('test'); expect(location.hash).not.toBe('test');
...@@ -176,7 +176,7 @@ describe('Multi-file store file actions', () => { ...@@ -176,7 +176,7 @@ describe('Multi-file store file actions', () => {
}); });
describe('getFileData', () => { describe('getFileData', () => {
let localFile = file(); let localFile;
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getFileData').and.returnValue(Promise.resolve({ spyOn(service, 'getFileData').and.returnValue(Promise.resolve({
...@@ -194,10 +194,17 @@ describe('Multi-file store file actions', () => { ...@@ -194,10 +194,17 @@ describe('Multi-file store file actions', () => {
}), }),
})); }));
localFile = file(); localFile = file('newCreate');
localFile.url = 'getFileDataURL'; localFile.url = 'getFileDataURL';
}); });
afterEach(() => {
store.dispatch('closeFile', {
file: localFile,
force: true,
});
});
it('calls the service', (done) => { it('calls the service', (done) => {
store.dispatch('getFileData', localFile) store.dispatch('getFileData', localFile)
.then(() => { .then(() => {
...@@ -268,7 +275,7 @@ describe('Multi-file store file actions', () => { ...@@ -268,7 +275,7 @@ describe('Multi-file store file actions', () => {
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getRawFileData').and.returnValue(Promise.resolve('raw')); spyOn(service, 'getRawFileData').and.returnValue(Promise.resolve('raw'));
tmpFile = file(); tmpFile = file('tmpFile');
}); });
it('calls getRawFileData service method', (done) => { it('calls getRawFileData service method', (done) => {
...@@ -294,7 +301,7 @@ describe('Multi-file store file actions', () => { ...@@ -294,7 +301,7 @@ describe('Multi-file store file actions', () => {
let tmpFile; let tmpFile;
beforeEach(() => { beforeEach(() => {
tmpFile = file(); tmpFile = file('tmpFile');
}); });
it('updates file content', (done) => { it('updates file content', (done) => {
......
...@@ -48,14 +48,14 @@ describe('Multi-file store actions', () => { ...@@ -48,14 +48,14 @@ describe('Multi-file store actions', () => {
describe('discardAllChanges', () => { describe('discardAllChanges', () => {
beforeEach(() => { beforeEach(() => {
store.state.openFiles.push(file()); store.state.openFiles.push(file('discardAll'));
store.state.openFiles[0].changed = true; store.state.openFiles[0].changed = true;
}); });
}); });
describe('closeAllFiles', () => { describe('closeAllFiles', () => {
beforeEach(() => { beforeEach(() => {
store.state.openFiles.push(file()); store.state.openFiles.push(file('closeAll'));
store.state.openFiles[0].opened = true; store.state.openFiles[0].opened = true;
}); });
...@@ -97,7 +97,7 @@ describe('Multi-file store actions', () => { ...@@ -97,7 +97,7 @@ describe('Multi-file store actions', () => {
it('opens discard popup if there are changed files', (done) => { it('opens discard popup if there are changed files', (done) => {
store.state.editMode = true; store.state.editMode = true;
store.state.openFiles.push(file()); store.state.openFiles.push(file('discardChanges'));
store.state.openFiles[0].changed = true; store.state.openFiles[0].changed = true;
store.dispatch('toggleEditMode') store.dispatch('toggleEditMode')
...@@ -111,7 +111,7 @@ describe('Multi-file store actions', () => { ...@@ -111,7 +111,7 @@ describe('Multi-file store actions', () => {
it('can force closed if there are changed files', (done) => { it('can force closed if there are changed files', (done) => {
store.state.editMode = true; store.state.editMode = true;
store.state.openFiles.push(file()); store.state.openFiles.push(file('forceClose'));
store.state.openFiles[0].changed = true; store.state.openFiles[0].changed = true;
store.dispatch('toggleEditMode', true) store.dispatch('toggleEditMode', true)
...@@ -124,7 +124,7 @@ describe('Multi-file store actions', () => { ...@@ -124,7 +124,7 @@ describe('Multi-file store actions', () => {
}); });
it('discards file changes', (done) => { it('discards file changes', (done) => {
const f = file(); const f = file('discard');
store.state.editMode = true; store.state.editMode = true;
store.state.openFiles.push(f); store.state.openFiles.push(f);
f.changed = true; f.changed = true;
...@@ -285,8 +285,8 @@ describe('Multi-file store actions', () => { ...@@ -285,8 +285,8 @@ describe('Multi-file store actions', () => {
}); });
it('adds commit data to changed files', (done) => { it('adds commit data to changed files', (done) => {
const changedFile = file(); const changedFile = file('changed');
const f = file(); const f = file('newfile');
changedFile.changed = true; changedFile.changed = true;
store.state.openFiles.push(changedFile, f); store.state.openFiles.push(changedFile, f);
......
...@@ -117,7 +117,7 @@ describe('Multi-file store file mutations', () => { ...@@ -117,7 +117,7 @@ describe('Multi-file store file mutations', () => {
describe('CREATE_TMP_FILE', () => { describe('CREATE_TMP_FILE', () => {
it('adds file into parent tree', () => { it('adds file into parent tree', () => {
const f = file(); const f = file('tmpFile');
mutations.CREATE_TMP_FILE(localState, { mutations.CREATE_TMP_FILE(localState, {
file: f, file: f,
......
...@@ -57,7 +57,7 @@ describe('Multi-file store tree mutations', () => { ...@@ -57,7 +57,7 @@ describe('Multi-file store tree mutations', () => {
describe('CREATE_TMP_TREE', () => { describe('CREATE_TMP_TREE', () => {
it('adds tree into parent tree', () => { it('adds tree into parent tree', () => {
const tmpEntry = file(); const tmpEntry = file('tmpTree');
mutations.CREATE_TMP_TREE(localState, { mutations.CREATE_TMP_TREE(localState, {
tmpEntry, tmpEntry,
......
...@@ -3383,7 +3383,7 @@ got@^3.2.0: ...@@ -3383,7 +3383,7 @@ got@^3.2.0:
read-all-stream "^3.0.0" read-all-stream "^3.0.0"
timed-out "^2.0.0" timed-out "^2.0.0"
got@^7.0.0: got@^7.1.0:
version "7.1.0" version "7.1.0"
resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a"
dependencies: dependencies:
...@@ -7594,9 +7594,9 @@ vue-hot-reload-api@^2.2.0: ...@@ -7594,9 +7594,9 @@ vue-hot-reload-api@^2.2.0:
version "2.2.4" version "2.2.4"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz#683bd1d026c0d3b3c937d5875679e9a87ec6cd8f" resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz#683bd1d026c0d3b3c937d5875679e9a87ec6cd8f"
vue-loader@^13.5.0: vue-loader@^13.7.0:
version "13.5.0" version "13.7.0"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.5.0.tgz#52f7b3790a267eff80012b77ea187a54586dd5d4" resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.7.0.tgz#4d6a35b169c2a0a488842fb95c85052105fa9729"
dependencies: dependencies:
consolidate "^0.14.0" consolidate "^0.14.0"
hash-sum "^1.0.2" hash-sum "^1.0.2"
...@@ -7612,11 +7612,11 @@ vue-loader@^13.5.0: ...@@ -7612,11 +7612,11 @@ vue-loader@^13.5.0:
vue-style-loader "^3.0.0" vue-style-loader "^3.0.0"
vue-template-es2015-compiler "^1.6.0" vue-template-es2015-compiler "^1.6.0"
vue-resource@^1.3.4: vue-resource@^1.3.5:
version "1.3.4" version "1.3.5"
resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.4.tgz#9fc0bdf6a2f5cab430129fc99d347b3deae7b099" resolved "https://registry.yarnpkg.com/vue-resource/-/vue-resource-1.3.5.tgz#021d8713e9d86a77e83169dfdd8eab6047369a71"
dependencies: dependencies:
got "^7.0.0" got "^7.1.0"
vue-router@^3.0.1: vue-router@^3.0.1:
version "3.0.1" version "3.0.1"
...@@ -7629,9 +7629,9 @@ vue-style-loader@^3.0.0: ...@@ -7629,9 +7629,9 @@ vue-style-loader@^3.0.0:
hash-sum "^1.0.2" hash-sum "^1.0.2"
loader-utils "^1.0.2" loader-utils "^1.0.2"
vue-template-compiler@^2.5.8: vue-template-compiler@^2.5.13:
version "2.5.8" version "2.5.13"
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.8.tgz#826ae77e1d5faa7fa5fca554f33872dde38de674" resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.13.tgz#12a2aa0ecd6158ac5e5f14d294b0993f399c3d38"
dependencies: dependencies:
de-indent "^1.0.2" de-indent "^1.0.2"
he "^1.1.0" he "^1.1.0"
...@@ -7640,9 +7640,9 @@ vue-template-es2015-compiler@^1.6.0: ...@@ -7640,9 +7640,9 @@ vue-template-es2015-compiler@^1.6.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18" resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
vue@^2.5.8: vue@^2.5.13:
version "2.5.8" version "2.5.13"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.8.tgz#f855c1c27255184a82225f4bef225473e8faf15b" resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.13.tgz#95bd31e20efcf7a7f39239c9aa6787ce8cf578e1"
vuex@^3.0.1: vuex@^3.0.1:
version "3.0.1" version "3.0.1"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册