1 /*
2 SPDX-FileCopyrightText: 2013 Andreas Cord-Landwehr <cordlandwehr@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5 */
6
7 #include "test_courseresource.h"
8 #include "../mocks/languagestub.h"
9 #include "core/language.h"
10 #include "core/phonemegroup.h"
11 #include "core/phrase.h"
12 #include "core/resources/courseresource.h"
13 #include "core/unit.h"
14 #include "resourcerepositorystub.h"
15 #include <QDebug>
16 #include <QFile>
17 #include <QIODevice>
18 #include <QSignalSpy>
19 #include <QTemporaryFile>
20 #include <QTest>
21 #include <QXmlSchema>
22 #include <QXmlSchemaValidator>
23
TestCourseResource()24 TestCourseResource::TestCourseResource()
25 {
26 }
27
init()28 void TestCourseResource::init()
29 {
30 }
31
cleanup()32 void TestCourseResource::cleanup()
33 {
34 }
35
loadCourseResource()36 void TestCourseResource::loadCourseResource()
37 {
38 std::shared_ptr<ILanguage> language(new LanguageStub("de"));
39 auto group = std::static_pointer_cast<LanguageStub>(language)->addPhonemeGroup("id", "title");
40 group->addPhoneme("g", "G");
41 group->addPhoneme("u", "U");
42 std::vector<std::shared_ptr<ILanguage>> languages;
43 languages.push_back(language);
44 ResourceRepositoryStub repository(languages);
45
46 const QString courseDirectory = qApp->applicationDirPath() + "/../autotests/unittests/data/courses/de/";
47 const QString courseFile = courseDirectory + "de.xml";
48
49 auto course = CourseResource::create(QUrl::fromLocalFile(courseFile), &repository);
50 QCOMPARE(course->file().toLocalFile(), courseFile);
51 QCOMPARE(course->id(), "de");
52 QCOMPARE(course->foreignId(), "artikulate-basic");
53 QCOMPARE(course->title(), "Artikulate Deutsch");
54 QCOMPARE(course->description(), "Ein Kurs in (hoch-)deutscher Aussprache.");
55 QVERIFY(course->language() != nullptr);
56 QCOMPARE(course->language()->id(), "de");
57 QCOMPARE(course->units().count(), 1);
58 QCOMPARE(course->units().first()->course(), course);
59
60 const auto unit = course->units().first();
61 QVERIFY(unit != nullptr);
62 QCOMPARE(unit->id(), "1");
63 QCOMPARE(unit->title(), QStringLiteral("Auf der Straße"));
64 QCOMPARE(unit->foreignId(), "{dd60f04a-eb37-44b7-9787-67aaf7d3578d}");
65 QCOMPARE(unit->course(), course);
66
67 QCOMPARE(unit->phrases().count(), 3);
68 // note: this test takes the silent assumption that phrases are added to the list in same
69 // order as they are defined in the file. This assumption should be made explicit or dropped
70 const auto firstPhrase = unit->phrases().first();
71 QVERIFY(firstPhrase != nullptr);
72 QCOMPARE(firstPhrase->id(), "1");
73 QCOMPARE(firstPhrase->foreignId(), "{3a4c1926-60d7-44c6-80d1-03165a641c75}");
74 QCOMPARE(firstPhrase->text(), "Guten Tag.");
75 QCOMPARE(firstPhrase->soundFileUrl(), courseDirectory + "de_01.ogg");
76 QCOMPARE(firstPhrase->type(), Phrase::Type::Sentence);
77 QCOMPARE(firstPhrase->phonemes().count(), 2);
78 }
79
loadCourseResourceSkipIncomplete()80 void TestCourseResource::loadCourseResourceSkipIncomplete()
81 {
82 std::shared_ptr<ILanguage> language(new LanguageStub("de"));
83 auto group = std::static_pointer_cast<LanguageStub>(language)->addPhonemeGroup("id", "title");
84 group->addPhoneme("g", "G");
85 group->addPhoneme("u", "U");
86 std::vector<std::shared_ptr<ILanguage>> languages;
87 languages.push_back(language);
88 ResourceRepositoryStub repository(languages);
89
90 const QString courseDirectory = "data/courses/de/";
91 const QString courseFile = courseDirectory + "de.xml";
92
93 auto course = CourseResource::create(QUrl::fromLocalFile(courseFile), &repository, true);
94 QCOMPARE(course->file().toLocalFile(), courseFile);
95 QCOMPARE(course->id(), "de");
96 QCOMPARE(course->units().count(), 1);
97 QCOMPARE(course->units().first()->course(), course);
98
99 const auto unit = course->units().first();
100 QVERIFY(unit != nullptr);
101 QCOMPARE(unit->id(), "1");
102 QCOMPARE(unit->phrases().count(), 2);
103 }
104
unitAddAndRemoveHandling()105 void TestCourseResource::unitAddAndRemoveHandling()
106 {
107 // boilerplate
108 std::shared_ptr<ILanguage> language(new LanguageStub("de"));
109 ResourceRepositoryStub repository({language});
110
111 const QString courseDirectory = qApp->applicationDirPath() + "/../autotests/unittests/data/courses/de/";
112 const QString courseFile = courseDirectory + "de.xml";
113 auto course = CourseResource::create(QUrl::fromLocalFile(courseFile), &repository);
114
115 // begin of test
116 auto unit = Unit::create();
117 unit->setId("testunit");
118 const int initialUnitNumber = course->units().count();
119 QCOMPARE(initialUnitNumber, 1);
120 QSignalSpy spyAboutToBeAdded(course.get(), SIGNAL(unitAboutToBeAdded(std::shared_ptr<Unit>, int)));
121 QSignalSpy spyAdded(course.get(), SIGNAL(unitAdded()));
122 QCOMPARE(spyAboutToBeAdded.count(), 0);
123 QCOMPARE(spyAdded.count(), 0);
124 auto sharedUnit = course->addUnit(std::move(unit));
125 QCOMPARE(course->units().count(), initialUnitNumber + 1);
126 QCOMPARE(spyAboutToBeAdded.count(), 1);
127 QCOMPARE(spyAdded.count(), 1);
128 QCOMPARE(sharedUnit->course(), course);
129 }
130
coursePropertyChanges()131 void TestCourseResource::coursePropertyChanges()
132 {
133 // boilerplate
134 std::shared_ptr<ILanguage> language(new LanguageStub("de"));
135 ResourceRepositoryStub repository({language});
136
137 const QString courseDirectory = qApp->applicationDirPath() + "/../autotests/unittests/data/courses/de/";
138 const QString courseFile = courseDirectory + "de.xml";
139 auto course = CourseResource::create(QUrl::fromLocalFile(courseFile), &repository);
140
141 // id
142 {
143 const QString value = "newId";
144 QSignalSpy spy(course.get(), SIGNAL(idChanged()));
145 QCOMPARE(spy.count(), 0);
146 course->setId(value);
147 QCOMPARE(course->id(), value);
148 QCOMPARE(spy.count(), 1);
149 }
150
151 // foreign id
152 {
153 const QString value = "newForeignId";
154 QSignalSpy spy(course.get(), SIGNAL(foreignIdChanged()));
155 QCOMPARE(spy.count(), 0);
156 course->setForeignId(value);
157 QCOMPARE(course->foreignId(), value);
158 QCOMPARE(spy.count(), 1);
159 }
160
161 // title
162 {
163 const QString value = "newTitle";
164 QSignalSpy spy(course.get(), SIGNAL(titleChanged()));
165 QCOMPARE(spy.count(), 0);
166 course->setTitle(value);
167 QCOMPARE(course->title(), value);
168 QCOMPARE(spy.count(), 1);
169 }
170
171 // title
172 {
173 const QString value = "newI18nTitle";
174 QSignalSpy spy(course.get(), SIGNAL(i18nTitleChanged()));
175 QCOMPARE(spy.count(), 0);
176 course->setI18nTitle(value);
177 QCOMPARE(course->i18nTitle(), value);
178 QCOMPARE(spy.count(), 1);
179 }
180
181 // description
182 {
183 const QString value = "newDescription";
184 QSignalSpy spy(course.get(), SIGNAL(descriptionChanged()));
185 QCOMPARE(spy.count(), 0);
186 course->setDescription(value);
187 QCOMPARE(course->description(), value);
188 QCOMPARE(spy.count(), 1);
189 }
190
191 // language
192 {
193 std::shared_ptr<Language> testLanguage;
194 QSignalSpy spy(course.get(), SIGNAL(languageChanged()));
195 QCOMPARE(spy.count(), 0);
196 course->setLanguage(testLanguage);
197 QCOMPARE(course->language(), testLanguage);
198 QCOMPARE(spy.count(), 1);
199 }
200 }
201
202 QTEST_GUILESS_MAIN(TestCourseResource)
203