Auto-generated, geolocation based chatrooms for universities.
- Git: Available here if you don't already have it.
- Visual Studio 2017: Click here and follow the instructions.
- npm: Click here to download node.js, which comes with npm.
npm is our client-side package manager.
- It stores any third-party packages in a
node_modules
folder inside src/Warbler.- Due to how big these packages can get, we have Git ignore that folder to keep our repository size down.
- Each time you pull commits from Github, it's a good habit to run
npm install
in the same directory as package.json.- This command will pull all the dependencies listed inside package.json.
- This way, we can easily keep track of what Warbler depends on without having to push and pull a bunch of big files from GitHub.
- If you need to add a dependency:
- Search for the package on the npm website.
- Run
npm install --save <package name>
.- The
--save
flag will update package.json'sdependencies
list.
- The
- Add the name of the package to the webpack vendor config.
- Import it in your component using the ES6
import
keyword - more details in the Front-End Development section.
- Open a terminal window and navigate to a folder that you want the Warbler code to be in.
git clone https://github.com/bcanseco/warbler.git Warbler
cd Warbler/src/Warbler
npm install
- Double-click Warbler.sln to open the project in Visual Studio.
To build, hit F5 in Visual Studio.
- This will trigger our webpack scripts.
- The vendor script takes third party dependencies, bunches them together, and spits them out into the
wwwroot/dist
folder. You'll see avendor.js
andvendor.css
, which contain Bootstrap, SignalR, and other codebases. These are referenced on all pages. - The normal script does the same thing but with our own code. You'll see our React components and other static files being spit out in the
wwwroot/dist
folder.
- The vendor script takes third party dependencies, bunches them together, and spits them out into the
- Visual Studio will then build the project.
- The webserver then (usually) runs on http://localhost:1337/ with Chrome.
- .NET Core is aware of the webpack script, and will hot reload any changes you make.
- For React scripts inside Component folders, no page refresh is necessary to see changes.
- For Less styles inside Component folders, no page refresh is necessary to see changes.
You can set breakpoints in the backend code to debug as needed. Use Debug
mode to use a local DB, or Release
to use the Azure DB.
You will need to make an appsettings.devkeys.json
file in the same directory as the appsettings.json file when running Warbler in development mode locally. This file contains our API keys and is ignored by git. The JSON object should look like this:
{
"ConnectionStrings": {
"WarblerProduction": "database connection string here"
},
"ApiKeys": {
"GooglePlaces": "google places key here"
}
}
Ask @bcanseco if you need these. These keys are set via Azure environment variables on the live site.
All new pages should be made using React components. For examples, see the Components folder.
-
Make a subfolder inside the Components folder, call it something appropriate.
-
Make an
index.jsx
file in there.- It's recommended that you copy and adapt the Dev one - be sure to keep the hot reloading stuff at the bottom.
- This file will contain your root component.
-
Make a
styles.less
file in there too - this is where your CSS will live. It gets imported at the top of the JSX index. -
If you want to render subcomponents (it's a good idea to make your code as modular as possible), feel free to make other JSX files in this folder or in further subfolders.
-
To actually use your component, a page needs to serve it. Here's an example of a controller returning a React component:
public IActionResult Index() { ViewData["Title"] = "Developer Panel"; ViewData["Heading"] = true; ViewData["Component"] = "Dev"; // Components/Dev return View("ReactComponent", ViewData); }
- Title - Title of the page. (REQUIRED)
- Component - The name of your component's subfolder. (REQUIRED)
- Heading - Render the heading partial on top of your component (default: false)
- OtherScripts - A list of scripts to inject before loading the component's script. You shouldn't need to use this; most libraries nowadays support ES6 importing (default: empty)
We use Less for CSS styling. Since Less is a superset of CSS, you can just write normal CSS if you don't want to take advantage of Less's features. All you have to do is make sure you're editing a .less
file. Please use kebab-case for identifiers.
If you want to import an image into the project, just drag it into the Graphics folder and rebuild. You can reference it as such: ~/dist/<file>.<ext>
- Note that React handles
src
attributes on images differently: https://stackoverflow.com/a/26065890/6609109
All tests should be in the Warbler.Tests project.
- Try to match the folder structure from Warbler
- e.g. If you're testing classes in Warbler/Misc, your tests should be in Warbler.Tests/Misc.
- This applies for subfolders too.
- Match the name of the class you're testing, but prepend "Test".
- e.g. If you're testing University.cs, your test class would be called "TestUniversity.cs".
- Use the naming convention
MethodName_ExpectedBehavior
.- When testing that the
CreateAsync()
method works in its expected (successful) scenario, you might useCreateAsync_Should_Create_A_New_University()
. - When testing that the
CreateAsync()
method fails in an expected yet unsuccessful scenario, you might useCreateAsync_Fails_When_University_Name_Is_Null()
.
- When testing that the
- We are using MSTest as our unit testing framework. You can read docs for it here. Key points:
- Test classes should have a
[TestClass]
attribute. - Test methods should have a
[TestMethod]
attribute. - You set up your own variables and test using the
Assert
class.- Type
Assert.
in Visual Studio to see available methods, e.g.AreEqual()
andIsFalse()
.
- Type
- Test classes should have a
- We have also imported a third party library called Moq. This library is useful for mocking a complicated part of the program when you only really want to test a small part of it.
- As a practical example, we'll use Moq with this method from SqlUniversityRepository:
public async Task SaveAsync() { // we want to test if this method gets called. await Context.SaveChangesAsync(); }
SaveChangesAsync()
is a method of theContext
property of the repository. Since we just want a test to ensure it gets called fromSaveAsync()
, here's how we can mock it:[TestMethod] public async Task SaveASync_Should_Save_Changes_On_Context() { var saveChangesCalled = false; // Create a fake WarblerDbContext var mockContext = new Mock<WarblerDbContext>(Options); // Watch its SaveChangesAsync() method to see if it gets called by the repo mockContext.Setup(x => x.SaveChangesAsync(default(CancellationToken))) .Callback(() => saveChangesCalled = true) .ReturnsAsync(0); // Attach it to the repo and call SaveAsync() var repo = new SqlUniversityRepository(mockContext.Object); await repo.SaveAsync(); Assert.IsTrue(saveChangesCalled); }
- You can view the full test class for this example here.
- As a practical example, we'll use Moq with this method from SqlUniversityRepository:
- You can run tests in Visual Studio by clicking on Test > Windows > Test Explorer.
- You can also run tests from a terminal using
dotnet test
.
- You can also run tests from a terminal using
You can access the docs site here.