forked from typeorm/typeorm
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: Allows valid non-object JSON to be retrieved in simple-json colu…
…mns (typeorm#6574) Fixes typeorm#5501
- Loading branch information
Showing
4 changed files
with
114 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,5 +12,4 @@ export class Post { | |
nullable: true | ||
}) | ||
jsonField: any; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import "reflect-metadata"; | ||
import { Connection } from "../../../src/connection/Connection"; | ||
import { closeTestingConnections, createTestingConnections, reloadTestingDatabases } from "../../utils/test-utils"; | ||
import { Post } from "./entity/Post"; | ||
import { expect } from "chai"; | ||
|
||
describe("github issues > #5501 Incorrect data loading from JSON string for column type 'simple-json'", () => { | ||
|
||
let connections: Connection[]; | ||
before(async () => { | ||
connections = await createTestingConnections({ | ||
entities: [Post], | ||
schemaCreate: true, | ||
dropSchema: true | ||
}); | ||
}); | ||
beforeEach(() => reloadTestingDatabases(connections)); | ||
after(() => closeTestingConnections(connections)); | ||
|
||
it("should correctly store simple-json field", () => Promise.all(connections.map(async (connection) => { | ||
let id = 0; | ||
const runTestCase = async (input: any, expected: any, message: string) => { | ||
id++; | ||
|
||
await connection.getRepository(Post).save({ id , jsonField: input }); | ||
|
||
const actual = ( | ||
await connection.createQueryBuilder() | ||
.from("Post", "post") | ||
.select("post.jsonField", "json") | ||
.where("post.id = :id", {id}) | ||
.getRawOne() | ||
)!.json; | ||
|
||
expect(actual).to.be.equal(expected, message); | ||
} | ||
|
||
await runTestCase("hello world", "\"hello world\"", "normal string"); | ||
await runTestCase("", "\"\"", "empty string"); | ||
await runTestCase("null", "\"null\"", "string containing the word null"); | ||
await runTestCase( { "key": "value" }, "{\"key\":\"value\"}", "object containing a key and string value"); | ||
await runTestCase([ "hello" ], "[\"hello\"]", "array containing a string"); | ||
await runTestCase(null, null, "a null object value"); | ||
await runTestCase(1, "1", "the real number 1"); | ||
await runTestCase(0.3, "0.3", "the number 0.3"); | ||
await runTestCase(true, "true", "the boolean value true"); | ||
await runTestCase( | ||
[ { hello: "earth", planet: true }, { hello: "moon", planet: false } ], | ||
"[{\"hello\":\"earth\",\"planet\":true},{\"hello\":\"moon\",\"planet\":false}]", | ||
"a complex object example" | ||
); | ||
}))); | ||
|
||
it("should correctly retrieve simple-json field", () => Promise.all(connections.map(async (connection) => { | ||
let id = 0; | ||
const runTestCase = async (input: string | null, expected: any, message: string) => { | ||
id++; | ||
await connection.createQueryBuilder() | ||
.insert() | ||
.into(Post) | ||
.values({id, jsonField: () => ':field'} as any) // A bit of a hack to get the raw value inserting | ||
.setParameter('field', input) | ||
.execute(); | ||
|
||
const actual = ( | ||
await connection.getRepository(Post).findOne({ where: { id } }) | ||
)!.jsonField; | ||
|
||
expect(actual).to.be.eql(expected, message); | ||
} | ||
|
||
await runTestCase("\"hello world\"", "hello world", "normal string"); | ||
await runTestCase("\"\"", "", "empty string"); | ||
await runTestCase("\"null\"", "null", "string containing the word null"); | ||
await runTestCase("{\"key\":\"value\"}", { "key": "value" }, "object containing a key and string value"); | ||
await runTestCase("[\"hello\"]", [ "hello" ], "array containing a string"); | ||
await runTestCase(null, null, "a null object value");; | ||
await runTestCase("1", 1, "the real number 1"); | ||
await runTestCase("0.3", 0.3, "the number 0.3"); | ||
await runTestCase("true", true, "the boolean value true"); | ||
await runTestCase( | ||
"[{\"hello\":\"earth\",\"planet\":true},{\"hello\":\"moon\",\"planet\":false}]", | ||
[{"hello":"earth","planet":true},{"hello":"moon","planet":false}], | ||
"a complex object example" | ||
); | ||
}))); | ||
|
||
it("should throw an error when the data in the database is invalid", () => Promise.all(connections.map(async (connection) => { | ||
const insert = (id: number, value: string | null) => | ||
connection.createQueryBuilder() | ||
.insert() | ||
.into(Post) | ||
.values({ id, jsonField: () => ':field' } as any) // A bit of a hack to get the raw value inserting | ||
.setParameter('field', value) | ||
.execute() | ||
|
||
// This was the likely data within the database in #4440 | ||
// This will happen if you've tried to manually insert the data in ways where | ||
// we aren't expecting you to - like switching the column type to a text & | ||
// trying to push a value into it that is an object. | ||
await insert(1, "[object Object]"); | ||
|
||
const repo = connection.getRepository(Post); | ||
|
||
const getJson = async (id: number) => | ||
( | ||
await repo.findOne({ where: { id } }) | ||
)!.jsonField; | ||
|
||
await expect(getJson(1)).to.be.rejected; | ||
}))); | ||
}); |