]> git.basschouten.com Git - openhab-addons.git/blob
d934987c4939257cd3b06581d42916255ca44512
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.transform.map.internal;
14
15 import static org.junit.jupiter.api.Assertions.*;
16
17 import java.io.File;
18 import java.io.FileReader;
19 import java.io.FileWriter;
20 import java.io.IOException;
21 import java.io.PrintStream;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.nio.file.Paths;
25 import java.util.Comparator;
26 import java.util.Locale;
27 import java.util.Properties;
28 import java.util.concurrent.Callable;
29 import java.util.stream.Stream;
30
31 import org.junit.jupiter.api.AfterEach;
32 import org.junit.jupiter.api.BeforeEach;
33 import org.junit.jupiter.api.Test;
34 import org.junit.jupiter.api.extension.ExtendWith;
35 import org.mockito.Mock;
36 import org.mockito.junit.jupiter.MockitoExtension;
37 import org.mockito.junit.jupiter.MockitoSettings;
38 import org.mockito.quality.Strictness;
39 import org.osgi.framework.BundleContext;
40
41 /**
42  * @author GaĆ«l L'hopital - Initial contribution
43  */
44 @ExtendWith(MockitoExtension.class)
45 @MockitoSettings(strictness = Strictness.LENIENT)
46 public class MapTransformationServiceTest {
47
48     private static final String SOURCE_CLOSED = "CLOSED";
49     private static final String SOURCE_UNKNOWN = "UNKNOWN";
50     private static final String EXISTING_FILENAME_DE = "map/doorstatus_de.map";
51     private static final String SHOULD_BE_LOCALIZED_FILENAME = "map/doorstatus.map";
52     private static final String DEFAULTED_FILENAME = "map/doorstatus_defaulted.map";
53     private static final String INEXISTING_FILENAME = "map/de.map";
54     private static final String BASE_FOLDER = "target";
55     private static final String SRC_FOLDER = "conf";
56     private static final String CONFIG_FOLDER = BASE_FOLDER + File.separator + SRC_FOLDER;
57     private static final String USED_FILENAME = CONFIG_FOLDER + File.separator + "transform/" + EXISTING_FILENAME_DE;
58
59     private @Mock BundleContext bundleContext;
60
61     private TestableMapTransformationService processor;
62
63     private class TestableMapTransformationService extends MapTransformationService {
64         @Override
65         protected String getSourcePath() {
66             return BASE_FOLDER + File.separator + super.getSourcePath();
67         }
68
69         @Override
70         protected Locale getLocale() {
71             return Locale.US;
72         }
73
74         @Override
75         public void activate(BundleContext context) {
76             super.activate(context);
77         }
78
79         @Override
80         public void deactivate() {
81             super.deactivate();
82         }
83     };
84
85     @BeforeEach
86     public void setUp() throws IOException {
87         processor = new TestableMapTransformationService();
88         processor.activate(bundleContext);
89         copyDirectory(SRC_FOLDER, CONFIG_FOLDER);
90     }
91
92     @AfterEach
93     public void tearDown() throws IOException {
94         processor.deactivate();
95
96         try (Stream<Path> walk = Files.walk(Path.of(CONFIG_FOLDER))) {
97             walk.sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete);
98         }
99     }
100
101     private void copyDirectory(String from, String to) throws IOException {
102         Files.walk(Paths.get(from)).forEach(fromPath -> {
103             Path toPath = Paths.get(to, fromPath.toString().substring(from.length()));
104             try {
105                 Files.copy(fromPath, toPath);
106             } catch (IOException e) {
107             }
108         });
109     }
110
111     @Test
112     public void testTransformByMap() throws Exception {
113         // Test that we find a translation in an existing file
114         String transformedResponse = processor.transform(EXISTING_FILENAME_DE, SOURCE_CLOSED);
115         assertEquals("zu", transformedResponse);
116
117         Properties properties = new Properties();
118         try (FileReader reader = new FileReader(USED_FILENAME); FileWriter writer = new FileWriter(USED_FILENAME)) {
119             properties.load(reader);
120             properties.setProperty(SOURCE_CLOSED, "changevalue");
121             properties.store(writer, "");
122
123             // This tests that the requested transformation file has been removed from
124             // the cache
125             waitForAssert(new Callable<Void>() {
126                 @Override
127                 public Void call() throws Exception {
128                     final String transformedResponse = processor.transform(EXISTING_FILENAME_DE, SOURCE_CLOSED);
129                     assertEquals("changevalue", transformedResponse);
130                     return null;
131                 }
132             }, 10000, 100);
133
134             properties.setProperty(SOURCE_CLOSED, "zu");
135             properties.store(writer, "");
136
137             waitForAssert(new Callable<Void>() {
138                 @Override
139                 public Void call() throws Exception {
140                     final String transformedResponse = processor.transform(EXISTING_FILENAME_DE, SOURCE_CLOSED);
141                     assertEquals("zu", transformedResponse);
142                     return null;
143                 }
144             }, 10000, 100);
145         } catch (IOException e1) {
146             PrintStream err = System.err;
147             if (err != null) {
148                 e1.printStackTrace(err);
149             }
150         }
151
152         // Checks that an unknown input in an existing file give the expected
153         // transformed response that shall be empty string (Issue #1107) if not found in the file
154         transformedResponse = processor.transform(EXISTING_FILENAME_DE, SOURCE_UNKNOWN);
155         assertEquals("", transformedResponse);
156
157         // Test that an inexisting file raises correct exception as expected
158         try {
159             transformedResponse = processor.transform(INEXISTING_FILENAME, SOURCE_CLOSED);
160             fail();
161         } catch (Exception e) {
162             // That's what we expect.
163         }
164
165         // Test that we find a localized version of desired file
166         transformedResponse = processor.transform(SHOULD_BE_LOCALIZED_FILENAME, SOURCE_CLOSED);
167         // as we don't know the real locale at the moment the
168         // test is run, we test that the string has actually been transformed
169         assertNotEquals(SOURCE_CLOSED, transformedResponse);
170         transformedResponse = processor.transform(SHOULD_BE_LOCALIZED_FILENAME, SOURCE_CLOSED);
171         assertNotEquals(SOURCE_CLOSED, transformedResponse);
172     }
173
174     @Test
175     public void testTransformByMapWithDefault() throws Exception {
176         // Standard behaviour with no default value
177         String transformedResponse = processor.transform(SHOULD_BE_LOCALIZED_FILENAME, "toBeDefaulted");
178         assertEquals("", transformedResponse);
179         // Modified behaviour with a file containing default value definition
180         transformedResponse = processor.transform(DEFAULTED_FILENAME, "toBeDefaulted");
181         assertEquals("Default Value", transformedResponse);
182     }
183
184     protected void waitForAssert(Callable<Void> assertion, int timeout, int sleepTime) throws Exception {
185         int waitingTime = 0;
186         while (waitingTime < timeout) {
187             try {
188                 assertion.call();
189                 return;
190             } catch (AssertionError error) {
191                 waitingTime += sleepTime;
192                 try {
193                     Thread.sleep(sleepTime);
194                 } catch (InterruptedException e) {
195                     throw new RuntimeException(e);
196                 }
197             }
198         }
199         assertion.call();
200     }
201 }