1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-06-06 22:46:29 +02:00

API: Resolves #941: Add support for "tags" property for note PUT request (#2649)

* API: Fix updation of tags when updating a note

* Add test for fix updation of tags

* Rewrite unit test and change variable name

* Use consistent variables and function calls

* Use default function call and change variable

* Handle case when tags is empty string

* Restructure test cases and improve tags check

* Update documentation
This commit is contained in:
Yuvaraj J 2020-03-14 00:14:47 +05:30 committed by GitHub
parent 8e2ba0d963
commit cda837247a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 5 deletions

View File

@ -183,11 +183,11 @@ class Command extends BaseCommand {
type: Database.enumId('fieldType', 'text'), type: Database.enumId('fieldType', 'text'),
description: 'If an image is provided, you can also specify an optional rectangle that will be used to crop the image. In format `{ x: x, y: y, width: width, height: height }`', description: 'If an image is provided, you can also specify an optional rectangle that will be used to crop the image. In format `{ x: x, y: y, width: width, height: height }`',
}); });
// tableFields.push({ tableFields.push({
// name: 'tags', name: 'tags',
// type: Database.enumId('fieldType', 'text'), type: Database.enumId('fieldType', 'text'),
// description: 'Comma-separated list of tags. eg. `tag1,tag2`.', description: 'Comma-separated list of tags. eg. `tag1,tag2`.',
// }); });
} }
lines.push(`# ${toTitleCase(tableName)}`); lines.push(`# ${toTitleCase(tableName)}`);

View File

@ -8,6 +8,7 @@ const Folder = require('lib/models/Folder');
const Resource = require('lib/models/Resource'); const Resource = require('lib/models/Resource');
const Note = require('lib/models/Note'); const Note = require('lib/models/Note');
const Tag = require('lib/models/Tag'); const Tag = require('lib/models/Tag');
const NoteTag = require('lib/models/NoteTag');
const { shim } = require('lib/shim'); const { shim } = require('lib/shim');
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
@ -326,4 +327,84 @@ describe('services_rest_Api', function() {
expect(response3.length).toBe(2); expect(response3.length).toBe(2);
})); }));
it('should update tags when updating notes', asyncTest(async () => {
const tag1 = await Tag.save({ title: 'mon étiquette 1' });
const tag2 = await Tag.save({ title: 'mon étiquette 2' });
const tag3 = await Tag.save({ title: 'mon étiquette 3' });
const note = await Note.save({
title: 'ma note un',
});
Tag.addNote(tag1.id, note.id);
Tag.addNote(tag2.id, note.id);
const response = await api.route('PUT', `notes/${note.id}`, null, JSON.stringify({
tags: `${tag1.title},${tag3.title}`,
}));
const tagIds = await NoteTag.tagIdsByNoteId(note.id);
expect(response.tags === `${tag1.title},${tag3.title}`).toBe(true);
expect(tagIds.length === 2).toBe(true);
expect(tagIds.includes(tag1.id)).toBe(true);
expect(tagIds.includes(tag3.id)).toBe(true);
}));
it('should create and update tags when updating notes', asyncTest(async () => {
const tag1 = await Tag.save({ title: 'mon étiquette 1' });
const tag2 = await Tag.save({ title: 'mon étiquette 2' });
const newTagTitle = 'mon étiquette 3';
const note = await Note.save({
title: 'ma note un',
});
Tag.addNote(tag1.id, note.id);
Tag.addNote(tag2.id, note.id);
const response = await api.route('PUT', `notes/${note.id}`, null, JSON.stringify({
tags: `${tag1.title},${newTagTitle}`,
}));
const newTag = await Tag.loadByTitle(newTagTitle);
const tagIds = await NoteTag.tagIdsByNoteId(note.id);
expect(response.tags === `${tag1.title},${newTag.title}`).toBe(true);
expect(tagIds.length === 2).toBe(true);
expect(tagIds.includes(tag1.id)).toBe(true);
expect(tagIds.includes(newTag.id)).toBe(true);
}));
it('should not update tags if tags is not mentioned when updating', asyncTest(async () => {
const tag1 = await Tag.save({ title: 'mon étiquette 1' });
const tag2 = await Tag.save({ title: 'mon étiquette 2' });
const note = await Note.save({
title: 'ma note un',
});
Tag.addNote(tag1.id, note.id);
Tag.addNote(tag2.id, note.id);
const response = await api.route('PUT', `notes/${note.id}`, null, JSON.stringify({
title: 'Some other title',
}));
const tagIds = await NoteTag.tagIdsByNoteId(note.id);
expect(response.tags === undefined).toBe(true);
expect(tagIds.length === 2).toBe(true);
expect(tagIds.includes(tag1.id)).toBe(true);
expect(tagIds.includes(tag2.id)).toBe(true);
}));
it('should remove tags from note if tags is set to empty string when updating', asyncTest(async () => {
const tag1 = await Tag.save({ title: 'mon étiquette 1' });
const tag2 = await Tag.save({ title: 'mon étiquette 2' });
const note = await Note.save({
title: 'ma note un',
});
Tag.addNote(tag1.id, note.id);
Tag.addNote(tag2.id, note.id);
const response = await api.route('PUT', `notes/${note.id}`, null, JSON.stringify({
tags: '',
}));
const tagIds = await NoteTag.tagIdsByNoteId(note.id);
expect(response.tags === '').toBe(true);
expect(tagIds.length === 0).toBe(true);
}));
}); });

View File

@ -451,6 +451,22 @@ class Api {
return note; return note;
} }
if (request.method === 'PUT') {
const note = await Note.load(id);
if (!note) throw new ErrorNotFound();
let updatedNote = await this.defaultAction_(BaseModel.TYPE_NOTE, request, id, link);
const requestNote = JSON.parse(request.body);
if (requestNote.tags || requestNote.tags === '') {
const tagTitles = requestNote.tags.split(',');
await Tag.setNoteTagsByTitles(id, tagTitles);
}
return updatedNote;
}
return this.defaultAction_(BaseModel.TYPE_NOTE, request, id, link); return this.defaultAction_(BaseModel.TYPE_NOTE, request, id, link);
} }