2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.persistence.jdbc.internal;
15 import static org.hamcrest.MatcherAssert.assertThat;
16 import static org.hamcrest.core.Is.is;
18 import java.util.ArrayList;
19 import java.util.HashMap;
20 import java.util.List;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.junit.jupiter.api.Assertions;
25 import org.junit.jupiter.api.BeforeEach;
26 import org.junit.jupiter.api.Test;
27 import org.junit.jupiter.api.extension.ExtendWith;
28 import org.mockito.Mock;
29 import org.mockito.Mockito;
30 import org.mockito.junit.jupiter.MockitoExtension;
31 import org.mockito.junit.jupiter.MockitoSettings;
32 import org.mockito.quality.Strictness;
33 import org.openhab.persistence.jdbc.internal.dto.ItemVO;
34 import org.slf4j.LoggerFactory;
36 import ch.qos.logback.classic.Level;
37 import ch.qos.logback.classic.Logger;
40 * Tests the {@link NamingStrategy} class.
42 * @author Jacob Laursen - Initial contribution
44 @ExtendWith(MockitoExtension.class)
45 @MockitoSettings(strictness = Strictness.LENIENT)
47 public class NamingStrategyTest {
48 private static final String ITEMS_MANAGE_TABLE_NAME = "items";
50 private @Mock @NonNullByDefault({}) JdbcConfiguration configurationMock;
51 private NamingStrategy namingStrategy = new NamingStrategy(configurationMock);
54 public void initialize() {
55 final Logger logger = (Logger) LoggerFactory.getLogger(NamingStrategy.class);
56 logger.setLevel(Level.OFF);
57 namingStrategy = new NamingStrategy(configurationMock);
61 public void getTableNameWhenInvalidItemNameThrows() {
62 Assertions.assertThrows(IllegalArgumentException.class, () -> {
63 namingStrategy.getTableName(1, "4Two");
68 public void getTableNameWhenUseRealItemNamesNameIsLowerCaseAndNumbered() {
69 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
70 Mockito.doReturn(false).when(configurationMock).getTableCaseSensitiveItemNames();
71 assertThat(namingStrategy.getTableName(1, "Test"), is("test_1"));
75 public void getTableNameWhenUseRealCaseSensitiveItemNamesNameIsSameCase() {
76 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
77 Mockito.doReturn(true).when(configurationMock).getTableCaseSensitiveItemNames();
78 assertThat(namingStrategy.getTableName(1, "Camel"), is("Camel"));
82 public void getTableNameWhenUseRealCaseSensitiveItemNamesNameIsSameCaseLower() {
83 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
84 Mockito.doReturn(true).when(configurationMock).getTableCaseSensitiveItemNames();
85 assertThat(namingStrategy.getTableName(1, "lower"), is("lower"));
89 public void getTableNameWhenNotUseRealItemNamesAndCount4NameHasLeavingZeros() {
90 Mockito.doReturn(false).when(configurationMock).getTableUseRealItemNames();
91 Mockito.doReturn(4).when(configurationMock).getTableIdDigitCount();
92 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
93 assertThat(namingStrategy.getTableName(2, "Test"), is("Item0002"));
97 public void getTableNameWhenNotUseRealItemNamesAndCount0() {
98 Mockito.doReturn(false).when(configurationMock).getTableUseRealItemNames();
99 Mockito.doReturn(0).when(configurationMock).getTableIdDigitCount();
100 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
101 assertThat(namingStrategy.getTableName(12345, "Test"), is("Item12345"));
105 public void prepareMigrationFromNumberedToRealNames() {
106 final int itemId = 1;
107 final String itemName = "Test";
108 final String tableName = "Item1";
110 List<ItemVO> actual = prepareMigrationRealItemNames(itemId, itemName, tableName);
112 assertTableName(actual, "Test");
116 public void prepareMigrationWithChangedPrefix() {
117 Mockito.doReturn(0).when(configurationMock).getTableIdDigitCount();
118 Mockito.doReturn(false).when(configurationMock).getTableUseRealItemNames();
120 final int itemId = 1;
121 final String itemName = "Test";
122 final String tableName = "Item1";
124 List<ItemVO> actual = prepareMigration(itemId, itemName, tableName, "item");
126 assertTableName(actual, "item1");
130 public void prepareMigrationShouldNotStopWhenEncounteringUnknownItem() {
131 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
132 Mockito.doReturn(true).when(configurationMock).getTableCaseSensitiveItemNames();
133 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
135 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(2);
136 itemIdToItemNameMap.put(1, "First");
137 itemIdToItemNameMap.put(3, "Third");
139 List<String> itemTables = new ArrayList<String>(3);
140 itemTables.add("Item1");
141 itemTables.add("Item2");
142 itemTables.add("Item3");
144 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
146 assertThat(actual.size(), is(2));
147 assertThat(actual.get(0).getNewTableName(), is("First"));
148 assertThat(actual.get(1).getNewTableName(), is("Third"));
152 public void prepareMigrationFromMixedNumberedToNumberedRealNames() {
153 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
154 Mockito.doReturn(false).when(configurationMock).getTableCaseSensitiveItemNames();
155 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
157 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(3);
158 itemIdToItemNameMap.put(1, "First");
159 itemIdToItemNameMap.put(2, "Second");
160 itemIdToItemNameMap.put(3, "Third");
162 List<String> itemTables = new ArrayList<String>(3);
163 itemTables.add("Item1");
164 itemTables.add("Item002");
165 itemTables.add("third_0003");
167 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
169 assertThat(actual.size(), is(3));
170 assertThat(actual.get(0).getNewTableName(), is("first_1"));
171 assertThat(actual.get(1).getNewTableName(), is("second_2"));
172 assertThat(actual.get(2).getNewTableName(), is("third_3"));
176 public void prepareMigrationFromMixedNumberedToCaseSensitiveRealNames() {
177 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
178 Mockito.doReturn(true).when(configurationMock).getTableCaseSensitiveItemNames();
179 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
181 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(3);
182 itemIdToItemNameMap.put(1, "First");
183 itemIdToItemNameMap.put(2, "Second");
184 itemIdToItemNameMap.put(3, "Third");
186 List<String> itemTables = new ArrayList<String>(3);
187 itemTables.add("Item1");
188 itemTables.add("Item002");
189 itemTables.add("third_0003");
191 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
193 assertThat(actual.size(), is(3));
194 assertThat(actual.get(0).getNewTableName(), is("First"));
195 assertThat(actual.get(1).getNewTableName(), is("Second"));
196 assertThat(actual.get(2).getNewTableName(), is("Third"));
200 public void prepareMigrationFromNumberedRealNamesToCaseSensitiveRealNames() {
201 final int itemId = 1;
202 final String itemName = "Test";
203 final String tableName = "test_0001";
205 List<ItemVO> actual = prepareMigrationRealItemNames(itemId, itemName, tableName, true);
207 assertTableName(actual, "Test");
211 public void prepareMigrationFromCaseSensitiveRealNamesToNumberedRealNames() {
212 final int itemId = 1;
213 final String itemName = "Test";
214 final String tableName = "Test";
216 List<ItemVO> actual = prepareMigrationRealItemNames(itemId, itemName, tableName, false);
218 assertTableName(actual, "test_0001");
222 public void prepareMigrationRealNamesWithTwoItemsWithDifferentCaseToNumbered() {
223 Mockito.doReturn(false).when(configurationMock).getTableUseRealItemNames();
224 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
225 Mockito.doReturn(1).when(configurationMock).getTableIdDigitCount();
227 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(2);
228 itemIdToItemNameMap.put(1, "MyItem");
229 itemIdToItemNameMap.put(2, "myItem");
231 List<String> itemTables = new ArrayList<String>(2);
232 itemTables.add("MyItem");
233 itemTables.add("myItem");
235 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
237 assertThat(actual.size(), is(2));
238 assertThat(actual.get(0).getNewTableName(), is("Item1"));
239 assertThat(actual.get(1).getNewTableName(), is("Item2"));
243 public void prepareMigrationNumberedWithTwoItemsWithDifferentCaseToNumberedRealNames() {
244 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
245 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
246 Mockito.doReturn(false).when(configurationMock).getTableCaseSensitiveItemNames();
248 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(2);
249 itemIdToItemNameMap.put(1, "MyItem");
250 itemIdToItemNameMap.put(2, "myItem");
252 List<String> itemTables = new ArrayList<String>(2);
253 itemTables.add("Item1");
254 itemTables.add("Item2");
256 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
258 assertThat(actual.size(), is(2));
259 assertThat(actual.get(0).getNewTableName(), is("myitem_1"));
260 assertThat(actual.get(1).getNewTableName(), is("myitem_2"));
264 public void prepareMigrationNumberedWithTwoItemsWithDifferentCaseToCaseSensitiveRealNames() {
265 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
266 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
267 Mockito.doReturn(true).when(configurationMock).getTableCaseSensitiveItemNames();
269 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(2);
270 itemIdToItemNameMap.put(1, "MyItem");
271 itemIdToItemNameMap.put(2, "myItem");
273 List<String> itemTables = new ArrayList<String>(2);
274 itemTables.add("Item1");
275 itemTables.add("Item2");
277 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
279 assertThat(actual.size(), is(2));
280 assertThat(actual.get(0).getNewTableName(), is("MyItem"));
281 assertThat(actual.get(1).getNewTableName(), is("myItem"));
285 public void prepareMigrationFromNumberedRealNamesToCaseSensitiveRealNamesWhenUnknownItemIdThenSkip() {
286 final int itemId = 2;
287 final String itemName = "Test";
288 final String tableName = "test_0001";
290 List<ItemVO> actual = prepareMigrationRealItemNames(itemId, itemName, tableName);
292 assertThat(actual.size(), is(0));
296 public void prepareMigrationFromNumberedRealNamesToNumbered() {
297 final int itemId = 1;
298 final String itemName = "Test";
299 final String tableName = "test_0001";
301 List<ItemVO> actual = prepareMigrationNumbered(itemId, itemName, tableName);
303 assertTableName(actual, "Item0001");
307 public void prepareMigrationFromNumberedToNumberedWithCorrectPadding() {
308 final int itemId = 1;
309 final String itemName = "Test";
310 final String tableName = "Item1";
312 List<ItemVO> actual = prepareMigrationNumbered(itemId, itemName, tableName, 2);
314 assertTableName(actual, "Item01");
318 public void prepareMigrationFromNumberedToNumberedExceedingPadding() {
319 final int itemId = 101;
320 final String itemName = "Test";
321 final String tableName = "Item0101";
323 List<ItemVO> actual = prepareMigrationNumbered(itemId, itemName, tableName, 2);
325 assertTableName(actual, "Item101");
329 public void prepareMigrationFromCaseSensitiveRealNamesToNumbered() {
330 final int itemId = 1;
331 final String itemName = "Test";
332 final String tableName = "Test";
334 List<ItemVO> actual = prepareMigrationNumbered(itemId, itemName, tableName);
336 assertTableName(actual, "Item0001");
340 public void prepareMigrationFromCaseSensitiveRealNamesToNumberedHavingUnderscore() {
341 final int itemId = 1;
342 final String itemName = "My_Test";
343 final String tableName = "My_Test";
345 List<ItemVO> actual = prepareMigrationNumbered(itemId, itemName, tableName);
347 assertTableName(actual, "Item0001");
351 public void prepareMigrationFromCaseSensitiveRealNamesHavingUnderscoreAndNumberToNumbered() {
352 final int itemId = 2;
353 final String itemName = "My_Test_1";
354 final String tableName = "My_Test_1";
356 List<ItemVO> actual = prepareMigrationNumbered(itemId, itemName, tableName);
358 assertTableName(actual, "Item0002");
362 public void prepareMigrationFromCaseSensitiveRealNamesToNumberedShouldSwap() {
363 Mockito.doReturn(false).when(configurationMock).getTableUseRealItemNames();
364 Mockito.doReturn("Item").when(configurationMock).getTableNamePrefix();
366 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(2);
367 itemIdToItemNameMap.put(1, "Item2");
368 itemIdToItemNameMap.put(2, "Item1");
370 List<String> itemTables = new ArrayList<String>(2);
371 itemTables.add("Item2");
372 itemTables.add("Item1");
374 List<ItemVO> actual = namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
376 assertThat(actual.size(), is(2));
377 assertThat(actual.get(0).getNewTableName(), is("Item1"));
378 assertThat(actual.get(1).getNewTableName(), is("Item2"));
382 public void prepareMigrationWhenConflictWithItemsManageTableThenSkip() {
383 final int itemId = 1;
384 final String itemName = "items";
385 final String tableName = "Item1";
387 List<ItemVO> actual = prepareMigrationRealItemNames(itemId, itemName, tableName);
389 assertThat(actual.size(), is(0));
392 private List<ItemVO> prepareMigrationNumbered(int itemId, String itemName, String tableName) {
393 return prepareMigrationNumbered(itemId, itemName, tableName, 4);
396 private List<ItemVO> prepareMigrationNumbered(int itemId, String itemName, String tableName,
397 int tableIdDigitCount) {
398 Mockito.doReturn(tableIdDigitCount).when(configurationMock).getTableIdDigitCount();
399 Mockito.doReturn(false).when(configurationMock).getTableUseRealItemNames();
400 return prepareMigration(itemId, itemName, tableName);
403 private List<ItemVO> prepareMigrationRealItemNames(int itemId, String itemName, String tableName) {
404 return prepareMigrationRealItemNames(itemId, itemName, tableName, true);
407 private List<ItemVO> prepareMigrationRealItemNames(int itemId, String itemName, String tableName,
408 boolean caseSensitive) {
409 Mockito.doReturn(4).when(configurationMock).getTableIdDigitCount();
410 Mockito.doReturn(true).when(configurationMock).getTableUseRealItemNames();
411 Mockito.doReturn(caseSensitive).when(configurationMock).getTableCaseSensitiveItemNames();
412 return prepareMigration(itemId, itemName, tableName);
415 private List<ItemVO> prepareMigration(int itemId, String itemName, String tableName) {
416 return prepareMigration(itemId, itemName, tableName, "Item");
419 private List<ItemVO> prepareMigration(int itemId, String itemName, String tableName, String prefix) {
420 Mockito.doReturn(prefix).when(configurationMock).getTableNamePrefix();
422 Map<Integer, String> itemIdToItemNameMap = getItemIdToItemNameMap(itemId, itemName);
423 List<String> itemTables = getItemTables(tableName);
425 return namingStrategy.prepareMigration(itemTables, itemIdToItemNameMap, ITEMS_MANAGE_TABLE_NAME);
428 private Map<Integer, String> getItemIdToItemNameMap(int itemId, String itemName) {
429 Map<Integer, String> itemIdToItemNameMap = new HashMap<>(1);
430 itemIdToItemNameMap.put(itemId, itemName);
431 return itemIdToItemNameMap;
434 private List<String> getItemTables(String tableName) {
435 List<String> itemTables = new ArrayList<String>(1);
436 itemTables.add(tableName);
440 private void assertTableName(List<ItemVO> actual, String expected) {
441 assertThat(actual.size(), is(1));
442 assertThat(actual.get(0).getNewTableName(), is(expected));