1 package org.dbunit.ext.postgresql;
2
3 import static org.assertj.core.api.Assertions.assertThat;
4
5 import java.io.StringReader;
6 import java.sql.Statement;
7 import java.sql.Types;
8 import java.util.Objects;
9
10 import org.dbunit.DatabaseEnvironment;
11 import org.dbunit.database.DatabaseConfig;
12 import org.dbunit.database.IDatabaseConnection;
13 import org.dbunit.dataset.Column;
14 import org.dbunit.dataset.IDataSet;
15 import org.dbunit.dataset.ITable;
16 import org.dbunit.dataset.ITableMetaData;
17 import org.dbunit.dataset.ReplacementDataSet;
18 import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
19 import org.dbunit.operation.DatabaseOperation;
20 import org.junit.jupiter.api.AfterEach;
21 import org.junit.jupiter.api.BeforeEach;
22 import org.junit.jupiter.api.Test;
23 import org.junit.jupiter.api.condition.EnabledIfSystemProperty;
24 import org.xml.sax.InputSource;
25
26 import com.fasterxml.jackson.databind.ObjectMapper;
27
28
29
30
31
32
33
34
35
36 @EnabledIfSystemProperty(named = "dbunit.profile", matches = "postgresql")
37 class PostgresqlJsonIT
38 {
39 private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
40
41 private IDatabaseConnection _connection;
42 private final String testTable = "json_test";
43
44 private static final String xmlData = "<?xml version=\"1.0\"?>" +
45 "<dataset>" +
46 "<JSON_TEST ID=\"1\" DATA=\"{"a":1}\" DATA_B=\"{"b":2}\" />" +
47 "<JSON_TEST ID=\"2\" DATA=\"[NULL]\" DATA_B=\"[NULL]\" />" +
48 "</dataset>";
49
50
51 @BeforeEach
52 protected void setUp() throws Exception
53 {
54
55 _connection = DatabaseEnvironment.getInstance().getConnection();
56 try (Statement stat = _connection.getConnection().createStatement())
57 {
58 stat.execute("DROP TABLE IF EXISTS " + testTable + ";");
59 stat.execute("CREATE TABLE " + testTable
60 + "(ID INTEGER NOT NULL, DATA json, DATA_B jsonb);");
61 }
62
63
64 _connection.close();
65 _connection = DatabaseEnvironment.getInstance().getConnection();
66 }
67
68 @AfterEach
69 protected void tearDown() throws Exception
70 {
71 if (!Objects.isNull(_connection))
72 {
73 try (Statement stat =
74 _connection.getConnection().createStatement())
75 {
76 stat.execute("DROP TABLE IF EXISTS " + testTable + ";");
77 } finally
78 {
79 _connection.close();
80 _connection = null;
81 }
82 }
83 }
84
85 @Test
86 void testJsonDataType_withJsonAndJsonbColumns_roundTripsThroughDatabase()
87 throws Exception
88 {
89 assertThat(_connection).as("didn't get a connection.").isNotNull();
90 final DatabaseConfig config = _connection.getConfig();
91 config.setProperty(DatabaseConfig.PROPERTY_DATATYPE_FACTORY,
92 new PostgresqlDataTypeFactory());
93
94 final ReplacementDataSet dataSet =
95 new ReplacementDataSet(new FlatXmlDataSetBuilder()
96 .build(new InputSource(new StringReader(xmlData))));
97 dataSet.addReplacementObject("[NULL]", null);
98 dataSet.setStrictReplacement(true);
99
100 final IDataSet metaDataSet = _connection.createDataSet();
101 final ITableMetaData itmd = metaDataSet.getTableMetaData(testTable);
102 boolean dataChecked = false;
103 boolean dataBChecked = false;
104 for (final Column col : itmd.getColumns())
105 {
106 if ("DATA".equalsIgnoreCase(col.getColumnName()))
107 {
108 dataChecked = true;
109 assertThat(col.getDataType().getSqlType())
110 .as("DATA column sql type.").isEqualTo(Types.OTHER);
111 assertThat(col.getSqlTypeName()).as("DATA column sql type name.")
112 .isEqualTo("json");
113 } else if ("DATA_B".equalsIgnoreCase(col.getColumnName()))
114 {
115 dataBChecked = true;
116 assertThat(col.getDataType().getSqlType())
117 .as("DATA_B column sql type.").isEqualTo(Types.OTHER);
118 assertThat(col.getSqlTypeName()).as("DATA_B column sql type name.")
119 .isEqualTo("jsonb");
120 }
121 }
122 assertThat(dataChecked).as("The DATA column should be present in the metadata.")
123 .isTrue();
124 assertThat(dataBChecked).as("The DATA_B column should be present in the metadata.")
125 .isTrue();
126
127 DatabaseOperation.CLEAN_INSERT.execute(_connection, dataSet);
128
129 final IDataSet actualDataSet = _connection.createDataSet();
130 final ITable actualTable = actualDataSet.getTable(testTable);
131
132
133
134
135 assertThat(OBJECT_MAPPER.readTree(
136 String.valueOf(actualTable.getValue(0, "DATA"))))
137 .as("DATA (json) row 0 should round-trip the same document.")
138 .isEqualTo(OBJECT_MAPPER.readTree("{\"a\":1}"));
139 assertThat(OBJECT_MAPPER.readTree(
140 String.valueOf(actualTable.getValue(0, "DATA_B"))))
141 .as("DATA_B (jsonb) row 0 should round-trip the same document.")
142 .isEqualTo(OBJECT_MAPPER.readTree("{\"b\":2}"));
143
144 assertThat(actualTable.getValue(1, "DATA"))
145 .as("DATA (json) row 1 should be null.").isNull();
146 assertThat(actualTable.getValue(1, "DATA_B"))
147 .as("DATA_B (jsonb) row 1 should be null.").isNull();
148 }
149 }