Commit 6e7b56e2 authored by Paul Slaughter's avatar Paul Slaughter

fixup! Add/remove snippet files in the edit view

parent 5c537cdc
......@@ -56,7 +56,6 @@ export default {
isUpdating: false,
newSnippet: false,
actions: [],
isLoaded: false,
};
},
computed: {
......@@ -133,8 +132,6 @@ export default {
this.newSnippet = false;
},
onSnippetFetch(snippetRes) {
this.isLoaded = true;
if (snippetRes.data.snippets.edges.length === 0) {
this.onNewSnippetFetched();
} else {
......@@ -221,11 +218,7 @@ export default {
:markdown-preview-path="markdownPreviewPath"
:markdown-docs-path="markdownDocsPath"
/>
<snippet-blob-actions-edit
:is-ready="isLoaded"
:init-blobs="blobs"
@actions="updateActions"
/>
<snippet-blob-actions-edit :init-blobs="blobs" @actions="updateActions" />
<snippet-visibility-edit
v-model="snippet.visibilityLevel"
......
......@@ -14,15 +14,12 @@ export default {
},
mixins: [glFeatureFlagsMixin()],
props: {
// TODO: Build reactivity for initBlobs.
// What happens if this changes (i.e. blobs are being loaded through pages)?
initBlobs: {
type: Array,
required: true,
},
isReady: {
type: Boolean,
required: false,
default: true,
},
},
data() {
return {
......@@ -74,14 +71,6 @@ export default {
},
},
watch: {
isReady: {
immediate: true,
handler(val) {
if (val) {
this.setup();
}
},
},
actions: {
immediate: true,
handler(val) {
......@@ -89,20 +78,20 @@ export default {
},
},
},
methods: {
setup() {
const blobs = this.initBlobs.map(decorateBlob);
const blobsById = blobs.reduce((acc, x) => Object.assign(acc, { [x.id]: x }), {});
created() {
const blobs = this.initBlobs.map(decorateBlob);
const blobsById = blobs.reduce((acc, x) => Object.assign(acc, { [x.id]: x }), {});
this.blobsOrig = blobsById;
this.blobs = cloneDeep(blobsById);
this.blobIds = blobs.map(x => x.id);
this.blobsOrig = blobsById;
this.blobs = cloneDeep(blobsById);
this.blobIds = blobs.map(x => x.id);
// Show 1 empty blob if none exist
if (!this.blobIds.length) {
this.addBlob();
}
},
// Show 1 empty blob if none exist
if (!this.blobIds.length) {
this.addBlob();
}
},
methods: {
updateBlobContent(id, content) {
const origBlob = this.blobsOrig[id];
const blob = this.blobs[id];
......
......@@ -18,13 +18,12 @@ export default {
props: {
blob: {
type: Object,
required: false,
default: null,
required: true,
},
canDelete: {
type: Boolean,
required: false,
default: false,
default: true,
},
showDelete: {
type: Boolean,
......
......@@ -5,6 +5,7 @@ exports[`Snippet Blob Edit component with loaded blob matches snapshot 1`] = `
class="file-holder snippet"
>
<blob-header-edit-stub
candelete="true"
data-qa-selector="file_name_field"
id="blob_local_7_file_path"
value="foo/bar/test.md"
......
......@@ -23,7 +23,6 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
wrapper = shallowMount(SnippetBlobActionsEdit, {
propsData: {
initBlobs: TEST_BLOBS,
isReady: false,
...props,
},
provide: {
......@@ -76,7 +75,7 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
${false} | ${'File'} | ${false} | ${false}
`('with feature flag = $featureFlag', ({ featureFlag, label, showDelete, showAdd }) => {
beforeEach(() => {
createComponent({ isReady: true }, featureFlag);
createComponent({}, featureFlag);
});
it('renders label', () => {
......@@ -100,132 +99,118 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
createComponent();
});
it('has no blobs yet', () => {
expect(findBlobsData()).toEqual([]);
it('emits no actions', () => {
expect(getLastActions()).toEqual([]);
});
describe('when isReady', () => {
beforeEach(async () => {
wrapper.setProps({ isReady: true });
it('shows blobs', () => {
expect(findBlobsData()).toEqual(buildBlobsDataExpectation(TEST_BLOBS_UNLOADED));
});
await wrapper.vm.$nextTick();
});
it('shows add button', () => {
const button = findAddButton();
it('emits no actions', () => {
expect(getLastActions()).toEqual([]);
});
expect(button.text()).toBe(`Add another file ${TEST_BLOBS.length}/${SNIPPET_MAX_BLOBS}`);
expect(button.props('disabled')).toBe(false);
});
it('shows blobs', () => {
expect(findBlobsData()).toEqual(buildBlobsDataExpectation(TEST_BLOBS_UNLOADED));
describe('when add is clicked', () => {
beforeEach(() => {
findAddButton().vm.$emit('click');
});
it('shows add button', () => {
const button = findAddButton();
expect(button.text()).toBe(`Add another file ${TEST_BLOBS.length}/${SNIPPET_MAX_BLOBS}`);
expect(button.props('disabled')).toBe(false);
it('adds blob with empty content', () => {
expect(findBlobsData()).toEqual(
buildBlobsDataExpectation([
...TEST_BLOBS_UNLOADED,
{
content: '',
isLoaded: true,
path: '',
},
]),
);
});
describe('when add is clicked', () => {
beforeEach(() => {
findAddButton().vm.$emit('click');
});
it('adds blob with empty content', () => {
expect(findBlobsData()).toEqual(
buildBlobsDataExpectation([
...TEST_BLOBS_UNLOADED,
{
content: '',
isLoaded: true,
path: '',
},
]),
);
});
it('emits action', () => {
expect(getLastActions()).toEqual([
expect.objectContaining({
action: SNIPPET_BLOB_ACTION_CREATE,
}),
]);
});
it('emits action', () => {
expect(getLastActions()).toEqual([
expect.objectContaining({
action: SNIPPET_BLOB_ACTION_CREATE,
}),
]);
});
});
describe('when blob is deleted', () => {
beforeEach(() => {
triggerBlobDelete(1);
});
describe('when blob is deleted', () => {
beforeEach(() => {
triggerBlobDelete(1);
});
it('removes blob', () => {
expect(findBlobsData()).toEqual(
buildBlobsDataExpectation(TEST_BLOBS_UNLOADED.slice(0, 1)),
);
});
it('removes blob', () => {
expect(findBlobsData()).toEqual(buildBlobsDataExpectation(TEST_BLOBS_UNLOADED.slice(0, 1)));
});
it('emits action', () => {
expect(getLastActions()).toEqual([
expect.objectContaining({
...testEntries.deleted.diff,
content: '',
}),
]);
});
it('emits action', () => {
expect(getLastActions()).toEqual([
expect.objectContaining({
...testEntries.deleted.diff,
content: '',
}),
]);
});
});
describe('when blob changes path', () => {
beforeEach(() => {
triggerBlobUpdate(0, { path: 'new/path' });
});
describe('when blob changes path', () => {
beforeEach(() => {
triggerBlobUpdate(0, { path: 'new/path' });
});
it('renames blob', () => {
expect(findBlobsData()[0]).toMatchObject({
blob: {
path: 'new/path',
},
});
it('renames blob', () => {
expect(findBlobsData()[0]).toMatchObject({
blob: {
path: 'new/path',
},
});
});
it('emits action', () => {
expect(getLastActions()).toMatchObject([
{
action: SNIPPET_BLOB_ACTION_MOVE,
filePath: 'new/path',
previousPath: testEntries.updated.diff.filePath,
},
]);
});
it('emits action', () => {
expect(getLastActions()).toMatchObject([
{
action: SNIPPET_BLOB_ACTION_MOVE,
filePath: 'new/path',
previousPath: testEntries.updated.diff.filePath,
},
]);
});
});
describe('when blob emits new content', () => {
const { content } = testEntries.updated.diff;
const originalContent = `${content}\noriginal content\n`;
describe('when blob emits new content', () => {
const { content } = testEntries.updated.diff;
const originalContent = `${content}\noriginal content\n`;
beforeEach(() => {
triggerBlobUpdate(0, { content: originalContent });
});
beforeEach(() => {
triggerBlobUpdate(0, { content: originalContent });
});
it('loads new content', () => {
expect(findBlobsData()[0]).toMatchObject({
blob: {
content: originalContent,
isLoaded: true,
},
});
it('loads new content', () => {
expect(findBlobsData()[0]).toMatchObject({
blob: {
content: originalContent,
isLoaded: true,
},
});
});
it('does not emit an action', () => {
expect(getLastActions()).toEqual([]);
});
it('does not emit an action', () => {
expect(getLastActions()).toEqual([]);
});
it('emits an action when content changes again', async () => {
triggerBlobUpdate(0, { content });
it('emits an action when content changes again', async () => {
triggerBlobUpdate(0, { content });
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
expect(getLastActions()).toEqual([testEntries.updated.diff]);
});
expect(getLastActions()).toEqual([testEntries.updated.diff]);
});
});
});
......
......@@ -141,7 +141,7 @@ describe('Snippet Blob Edit component', () => {
});
it('shows blob header', () => {
const { canDelete = false, showDelete = false } = props;
const { canDelete = true, showDelete = false } = props;
expect(findHeader().props()).toMatchObject({
canDelete,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment